annotate vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php @ 12:7a779792577d

Update Drupal core to v8.4.5 (via Composer)
author Chris Cannam
date Fri, 23 Feb 2018 15:52:07 +0000
parents 4c8ae668cc8c
children 5fb285c0d0e3
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace PhpParser\PrettyPrinter;
Chris@0 4
Chris@0 5 use PhpParser\Node;
Chris@0 6 use PhpParser\Node\Expr;
Chris@0 7 use PhpParser\Node\Expr\AssignOp;
Chris@0 8 use PhpParser\Node\Expr\BinaryOp;
Chris@0 9 use PhpParser\Node\Expr\Cast;
Chris@0 10 use PhpParser\Node\Name;
Chris@0 11 use PhpParser\Node\Scalar;
Chris@0 12 use PhpParser\Node\Scalar\MagicConst;
Chris@0 13 use PhpParser\Node\Stmt;
Chris@0 14 use PhpParser\PrettyPrinterAbstract;
Chris@0 15
Chris@0 16 class Standard extends PrettyPrinterAbstract
Chris@0 17 {
Chris@0 18 // Special nodes
Chris@0 19
Chris@0 20 protected function pParam(Node\Param $node) {
Chris@0 21 return ($node->type ? $this->pType($node->type) . ' ' : '')
Chris@0 22 . ($node->byRef ? '&' : '')
Chris@0 23 . ($node->variadic ? '...' : '')
Chris@0 24 . '$' . $node->name
Chris@0 25 . ($node->default ? ' = ' . $this->p($node->default) : '');
Chris@0 26 }
Chris@0 27
Chris@0 28 protected function pArg(Node\Arg $node) {
Chris@0 29 return ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value);
Chris@0 30 }
Chris@0 31
Chris@0 32 protected function pConst(Node\Const_ $node) {
Chris@0 33 return $node->name . ' = ' . $this->p($node->value);
Chris@0 34 }
Chris@0 35
Chris@0 36 protected function pNullableType(Node\NullableType $node) {
Chris@0 37 return '?' . $this->pType($node->type);
Chris@0 38 }
Chris@0 39
Chris@0 40 // Names
Chris@0 41
Chris@0 42 protected function pName(Name $node) {
Chris@0 43 return implode('\\', $node->parts);
Chris@0 44 }
Chris@0 45
Chris@0 46 protected function pName_FullyQualified(Name\FullyQualified $node) {
Chris@0 47 return '\\' . implode('\\', $node->parts);
Chris@0 48 }
Chris@0 49
Chris@0 50 protected function pName_Relative(Name\Relative $node) {
Chris@0 51 return 'namespace\\' . implode('\\', $node->parts);
Chris@0 52 }
Chris@0 53
Chris@0 54 // Magic Constants
Chris@0 55
Chris@0 56 protected function pScalar_MagicConst_Class(MagicConst\Class_ $node) {
Chris@0 57 return '__CLASS__';
Chris@0 58 }
Chris@0 59
Chris@0 60 protected function pScalar_MagicConst_Dir(MagicConst\Dir $node) {
Chris@0 61 return '__DIR__';
Chris@0 62 }
Chris@0 63
Chris@0 64 protected function pScalar_MagicConst_File(MagicConst\File $node) {
Chris@0 65 return '__FILE__';
Chris@0 66 }
Chris@0 67
Chris@0 68 protected function pScalar_MagicConst_Function(MagicConst\Function_ $node) {
Chris@0 69 return '__FUNCTION__';
Chris@0 70 }
Chris@0 71
Chris@0 72 protected function pScalar_MagicConst_Line(MagicConst\Line $node) {
Chris@0 73 return '__LINE__';
Chris@0 74 }
Chris@0 75
Chris@0 76 protected function pScalar_MagicConst_Method(MagicConst\Method $node) {
Chris@0 77 return '__METHOD__';
Chris@0 78 }
Chris@0 79
Chris@0 80 protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node) {
Chris@0 81 return '__NAMESPACE__';
Chris@0 82 }
Chris@0 83
Chris@0 84 protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node) {
Chris@0 85 return '__TRAIT__';
Chris@0 86 }
Chris@0 87
Chris@0 88 // Scalars
Chris@0 89
Chris@0 90 protected function pScalar_String(Scalar\String_ $node) {
Chris@0 91 $kind = $node->getAttribute('kind', Scalar\String_::KIND_SINGLE_QUOTED);
Chris@0 92 switch ($kind) {
Chris@0 93 case Scalar\String_::KIND_NOWDOC:
Chris@0 94 $label = $node->getAttribute('docLabel');
Chris@0 95 if ($label && !$this->containsEndLabel($node->value, $label)) {
Chris@0 96 if ($node->value === '') {
Chris@0 97 return $this->pNoIndent("<<<'$label'\n$label") . $this->docStringEndToken;
Chris@0 98 }
Chris@0 99
Chris@0 100 return $this->pNoIndent("<<<'$label'\n$node->value\n$label")
Chris@0 101 . $this->docStringEndToken;
Chris@0 102 }
Chris@0 103 /* break missing intentionally */
Chris@0 104 case Scalar\String_::KIND_SINGLE_QUOTED:
Chris@0 105 return '\'' . $this->pNoIndent(addcslashes($node->value, '\'\\')) . '\'';
Chris@0 106 case Scalar\String_::KIND_HEREDOC:
Chris@0 107 $label = $node->getAttribute('docLabel');
Chris@0 108 if ($label && !$this->containsEndLabel($node->value, $label)) {
Chris@0 109 if ($node->value === '') {
Chris@0 110 return $this->pNoIndent("<<<$label\n$label") . $this->docStringEndToken;
Chris@0 111 }
Chris@0 112
Chris@0 113 $escaped = $this->escapeString($node->value, null);
Chris@0 114 return $this->pNoIndent("<<<$label\n" . $escaped ."\n$label")
Chris@0 115 . $this->docStringEndToken;
Chris@0 116 }
Chris@0 117 /* break missing intentionally */
Chris@0 118 case Scalar\String_::KIND_DOUBLE_QUOTED:
Chris@0 119 return '"' . $this->escapeString($node->value, '"') . '"';
Chris@0 120 }
Chris@0 121 throw new \Exception('Invalid string kind');
Chris@0 122 }
Chris@0 123
Chris@0 124 protected function pScalar_Encapsed(Scalar\Encapsed $node) {
Chris@0 125 if ($node->getAttribute('kind') === Scalar\String_::KIND_HEREDOC) {
Chris@0 126 $label = $node->getAttribute('docLabel');
Chris@0 127 if ($label && !$this->encapsedContainsEndLabel($node->parts, $label)) {
Chris@0 128 if (count($node->parts) === 1
Chris@0 129 && $node->parts[0] instanceof Scalar\EncapsedStringPart
Chris@0 130 && $node->parts[0]->value === ''
Chris@0 131 ) {
Chris@0 132 return $this->pNoIndent("<<<$label\n$label") . $this->docStringEndToken;
Chris@0 133 }
Chris@0 134
Chris@0 135 return $this->pNoIndent(
Chris@0 136 "<<<$label\n" . $this->pEncapsList($node->parts, null) . "\n$label"
Chris@0 137 ) . $this->docStringEndToken;
Chris@0 138 }
Chris@0 139 }
Chris@0 140 return '"' . $this->pEncapsList($node->parts, '"') . '"';
Chris@0 141 }
Chris@0 142
Chris@0 143 protected function pScalar_LNumber(Scalar\LNumber $node) {
Chris@0 144 if ($node->value === -\PHP_INT_MAX-1) {
Chris@0 145 // PHP_INT_MIN cannot be represented as a literal,
Chris@0 146 // because the sign is not part of the literal
Chris@0 147 return '(-' . \PHP_INT_MAX . '-1)';
Chris@0 148 }
Chris@0 149
Chris@0 150 $kind = $node->getAttribute('kind', Scalar\LNumber::KIND_DEC);
Chris@0 151 if (Scalar\LNumber::KIND_DEC === $kind) {
Chris@0 152 return (string) $node->value;
Chris@0 153 }
Chris@0 154
Chris@0 155 $sign = $node->value < 0 ? '-' : '';
Chris@0 156 $str = (string) $node->value;
Chris@0 157 switch ($kind) {
Chris@0 158 case Scalar\LNumber::KIND_BIN:
Chris@0 159 return $sign . '0b' . base_convert($str, 10, 2);
Chris@0 160 case Scalar\LNumber::KIND_OCT:
Chris@0 161 return $sign . '0' . base_convert($str, 10, 8);
Chris@0 162 case Scalar\LNumber::KIND_HEX:
Chris@0 163 return $sign . '0x' . base_convert($str, 10, 16);
Chris@0 164 }
Chris@0 165 throw new \Exception('Invalid number kind');
Chris@0 166 }
Chris@0 167
Chris@0 168 protected function pScalar_DNumber(Scalar\DNumber $node) {
Chris@0 169 if (!is_finite($node->value)) {
Chris@0 170 if ($node->value === \INF) {
Chris@0 171 return '\INF';
Chris@0 172 } elseif ($node->value === -\INF) {
Chris@0 173 return '-\INF';
Chris@0 174 } else {
Chris@0 175 return '\NAN';
Chris@0 176 }
Chris@0 177 }
Chris@0 178
Chris@0 179 // Try to find a short full-precision representation
Chris@0 180 $stringValue = sprintf('%.16G', $node->value);
Chris@0 181 if ($node->value !== (double) $stringValue) {
Chris@0 182 $stringValue = sprintf('%.17G', $node->value);
Chris@0 183 }
Chris@0 184
Chris@0 185 // %G is locale dependent and there exists no locale-independent alternative. We don't want
Chris@0 186 // mess with switching locales here, so let's assume that a comma is the only non-standard
Chris@0 187 // decimal separator we may encounter...
Chris@0 188 $stringValue = str_replace(',', '.', $stringValue);
Chris@0 189
Chris@0 190 // ensure that number is really printed as float
Chris@0 191 return preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue;
Chris@0 192 }
Chris@0 193
Chris@0 194 // Assignments
Chris@0 195
Chris@0 196 protected function pExpr_Assign(Expr\Assign $node) {
Chris@0 197 return $this->pInfixOp('Expr_Assign', $node->var, ' = ', $node->expr);
Chris@0 198 }
Chris@0 199
Chris@0 200 protected function pExpr_AssignRef(Expr\AssignRef $node) {
Chris@0 201 return $this->pInfixOp('Expr_AssignRef', $node->var, ' =& ', $node->expr);
Chris@0 202 }
Chris@0 203
Chris@0 204 protected function pExpr_AssignOp_Plus(AssignOp\Plus $node) {
Chris@0 205 return $this->pInfixOp('Expr_AssignOp_Plus', $node->var, ' += ', $node->expr);
Chris@0 206 }
Chris@0 207
Chris@0 208 protected function pExpr_AssignOp_Minus(AssignOp\Minus $node) {
Chris@0 209 return $this->pInfixOp('Expr_AssignOp_Minus', $node->var, ' -= ', $node->expr);
Chris@0 210 }
Chris@0 211
Chris@0 212 protected function pExpr_AssignOp_Mul(AssignOp\Mul $node) {
Chris@0 213 return $this->pInfixOp('Expr_AssignOp_Mul', $node->var, ' *= ', $node->expr);
Chris@0 214 }
Chris@0 215
Chris@0 216 protected function pExpr_AssignOp_Div(AssignOp\Div $node) {
Chris@0 217 return $this->pInfixOp('Expr_AssignOp_Div', $node->var, ' /= ', $node->expr);
Chris@0 218 }
Chris@0 219
Chris@0 220 protected function pExpr_AssignOp_Concat(AssignOp\Concat $node) {
Chris@0 221 return $this->pInfixOp('Expr_AssignOp_Concat', $node->var, ' .= ', $node->expr);
Chris@0 222 }
Chris@0 223
Chris@0 224 protected function pExpr_AssignOp_Mod(AssignOp\Mod $node) {
Chris@0 225 return $this->pInfixOp('Expr_AssignOp_Mod', $node->var, ' %= ', $node->expr);
Chris@0 226 }
Chris@0 227
Chris@0 228 protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node) {
Chris@0 229 return $this->pInfixOp('Expr_AssignOp_BitwiseAnd', $node->var, ' &= ', $node->expr);
Chris@0 230 }
Chris@0 231
Chris@0 232 protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node) {
Chris@0 233 return $this->pInfixOp('Expr_AssignOp_BitwiseOr', $node->var, ' |= ', $node->expr);
Chris@0 234 }
Chris@0 235
Chris@0 236 protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node) {
Chris@0 237 return $this->pInfixOp('Expr_AssignOp_BitwiseXor', $node->var, ' ^= ', $node->expr);
Chris@0 238 }
Chris@0 239
Chris@0 240 protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node) {
Chris@0 241 return $this->pInfixOp('Expr_AssignOp_ShiftLeft', $node->var, ' <<= ', $node->expr);
Chris@0 242 }
Chris@0 243
Chris@0 244 protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node) {
Chris@0 245 return $this->pInfixOp('Expr_AssignOp_ShiftRight', $node->var, ' >>= ', $node->expr);
Chris@0 246 }
Chris@0 247
Chris@0 248 protected function pExpr_AssignOp_Pow(AssignOp\Pow $node) {
Chris@0 249 return $this->pInfixOp('Expr_AssignOp_Pow', $node->var, ' **= ', $node->expr);
Chris@0 250 }
Chris@0 251
Chris@0 252 // Binary expressions
Chris@0 253
Chris@0 254 protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node) {
Chris@0 255 return $this->pInfixOp('Expr_BinaryOp_Plus', $node->left, ' + ', $node->right);
Chris@0 256 }
Chris@0 257
Chris@0 258 protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node) {
Chris@0 259 return $this->pInfixOp('Expr_BinaryOp_Minus', $node->left, ' - ', $node->right);
Chris@0 260 }
Chris@0 261
Chris@0 262 protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node) {
Chris@0 263 return $this->pInfixOp('Expr_BinaryOp_Mul', $node->left, ' * ', $node->right);
Chris@0 264 }
Chris@0 265
Chris@0 266 protected function pExpr_BinaryOp_Div(BinaryOp\Div $node) {
Chris@0 267 return $this->pInfixOp('Expr_BinaryOp_Div', $node->left, ' / ', $node->right);
Chris@0 268 }
Chris@0 269
Chris@0 270 protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node) {
Chris@0 271 return $this->pInfixOp('Expr_BinaryOp_Concat', $node->left, ' . ', $node->right);
Chris@0 272 }
Chris@0 273
Chris@0 274 protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node) {
Chris@0 275 return $this->pInfixOp('Expr_BinaryOp_Mod', $node->left, ' % ', $node->right);
Chris@0 276 }
Chris@0 277
Chris@0 278 protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node) {
Chris@0 279 return $this->pInfixOp('Expr_BinaryOp_BooleanAnd', $node->left, ' && ', $node->right);
Chris@0 280 }
Chris@0 281
Chris@0 282 protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node) {
Chris@0 283 return $this->pInfixOp('Expr_BinaryOp_BooleanOr', $node->left, ' || ', $node->right);
Chris@0 284 }
Chris@0 285
Chris@0 286 protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node) {
Chris@0 287 return $this->pInfixOp('Expr_BinaryOp_BitwiseAnd', $node->left, ' & ', $node->right);
Chris@0 288 }
Chris@0 289
Chris@0 290 protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node) {
Chris@0 291 return $this->pInfixOp('Expr_BinaryOp_BitwiseOr', $node->left, ' | ', $node->right);
Chris@0 292 }
Chris@0 293
Chris@0 294 protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node) {
Chris@0 295 return $this->pInfixOp('Expr_BinaryOp_BitwiseXor', $node->left, ' ^ ', $node->right);
Chris@0 296 }
Chris@0 297
Chris@0 298 protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node) {
Chris@0 299 return $this->pInfixOp('Expr_BinaryOp_ShiftLeft', $node->left, ' << ', $node->right);
Chris@0 300 }
Chris@0 301
Chris@0 302 protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node) {
Chris@0 303 return $this->pInfixOp('Expr_BinaryOp_ShiftRight', $node->left, ' >> ', $node->right);
Chris@0 304 }
Chris@0 305
Chris@0 306 protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node) {
Chris@0 307 return $this->pInfixOp('Expr_BinaryOp_Pow', $node->left, ' ** ', $node->right);
Chris@0 308 }
Chris@0 309
Chris@0 310 protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node) {
Chris@0 311 return $this->pInfixOp('Expr_BinaryOp_LogicalAnd', $node->left, ' and ', $node->right);
Chris@0 312 }
Chris@0 313
Chris@0 314 protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node) {
Chris@0 315 return $this->pInfixOp('Expr_BinaryOp_LogicalOr', $node->left, ' or ', $node->right);
Chris@0 316 }
Chris@0 317
Chris@0 318 protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node) {
Chris@0 319 return $this->pInfixOp('Expr_BinaryOp_LogicalXor', $node->left, ' xor ', $node->right);
Chris@0 320 }
Chris@0 321
Chris@0 322 protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node) {
Chris@0 323 return $this->pInfixOp('Expr_BinaryOp_Equal', $node->left, ' == ', $node->right);
Chris@0 324 }
Chris@0 325
Chris@0 326 protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node) {
Chris@0 327 return $this->pInfixOp('Expr_BinaryOp_NotEqual', $node->left, ' != ', $node->right);
Chris@0 328 }
Chris@0 329
Chris@0 330 protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node) {
Chris@0 331 return $this->pInfixOp('Expr_BinaryOp_Identical', $node->left, ' === ', $node->right);
Chris@0 332 }
Chris@0 333
Chris@0 334 protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node) {
Chris@0 335 return $this->pInfixOp('Expr_BinaryOp_NotIdentical', $node->left, ' !== ', $node->right);
Chris@0 336 }
Chris@0 337
Chris@0 338 protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node) {
Chris@0 339 return $this->pInfixOp('Expr_BinaryOp_Spaceship', $node->left, ' <=> ', $node->right);
Chris@0 340 }
Chris@0 341
Chris@0 342 protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node) {
Chris@0 343 return $this->pInfixOp('Expr_BinaryOp_Greater', $node->left, ' > ', $node->right);
Chris@0 344 }
Chris@0 345
Chris@0 346 protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node) {
Chris@0 347 return $this->pInfixOp('Expr_BinaryOp_GreaterOrEqual', $node->left, ' >= ', $node->right);
Chris@0 348 }
Chris@0 349
Chris@0 350 protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node) {
Chris@0 351 return $this->pInfixOp('Expr_BinaryOp_Smaller', $node->left, ' < ', $node->right);
Chris@0 352 }
Chris@0 353
Chris@0 354 protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node) {
Chris@0 355 return $this->pInfixOp('Expr_BinaryOp_SmallerOrEqual', $node->left, ' <= ', $node->right);
Chris@0 356 }
Chris@0 357
Chris@0 358 protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node) {
Chris@0 359 return $this->pInfixOp('Expr_BinaryOp_Coalesce', $node->left, ' ?? ', $node->right);
Chris@0 360 }
Chris@0 361
Chris@0 362 protected function pExpr_Instanceof(Expr\Instanceof_ $node) {
Chris@0 363 return $this->pInfixOp('Expr_Instanceof', $node->expr, ' instanceof ', $node->class);
Chris@0 364 }
Chris@0 365
Chris@0 366 // Unary expressions
Chris@0 367
Chris@0 368 protected function pExpr_BooleanNot(Expr\BooleanNot $node) {
Chris@0 369 return $this->pPrefixOp('Expr_BooleanNot', '!', $node->expr);
Chris@0 370 }
Chris@0 371
Chris@0 372 protected function pExpr_BitwiseNot(Expr\BitwiseNot $node) {
Chris@0 373 return $this->pPrefixOp('Expr_BitwiseNot', '~', $node->expr);
Chris@0 374 }
Chris@0 375
Chris@0 376 protected function pExpr_UnaryMinus(Expr\UnaryMinus $node) {
Chris@12 377 if ($node->expr instanceof Expr\UnaryMinus || $node->expr instanceof Expr\PreDec) {
Chris@12 378 // Enforce -(-$expr) instead of --$expr
Chris@12 379 return '-(' . $this->p($node->expr) . ')';
Chris@12 380 }
Chris@0 381 return $this->pPrefixOp('Expr_UnaryMinus', '-', $node->expr);
Chris@0 382 }
Chris@0 383
Chris@0 384 protected function pExpr_UnaryPlus(Expr\UnaryPlus $node) {
Chris@12 385 if ($node->expr instanceof Expr\UnaryPlus || $node->expr instanceof Expr\PreInc) {
Chris@12 386 // Enforce +(+$expr) instead of ++$expr
Chris@12 387 return '+(' . $this->p($node->expr) . ')';
Chris@12 388 }
Chris@0 389 return $this->pPrefixOp('Expr_UnaryPlus', '+', $node->expr);
Chris@0 390 }
Chris@0 391
Chris@0 392 protected function pExpr_PreInc(Expr\PreInc $node) {
Chris@0 393 return $this->pPrefixOp('Expr_PreInc', '++', $node->var);
Chris@0 394 }
Chris@0 395
Chris@0 396 protected function pExpr_PreDec(Expr\PreDec $node) {
Chris@0 397 return $this->pPrefixOp('Expr_PreDec', '--', $node->var);
Chris@0 398 }
Chris@0 399
Chris@0 400 protected function pExpr_PostInc(Expr\PostInc $node) {
Chris@0 401 return $this->pPostfixOp('Expr_PostInc', $node->var, '++');
Chris@0 402 }
Chris@0 403
Chris@0 404 protected function pExpr_PostDec(Expr\PostDec $node) {
Chris@0 405 return $this->pPostfixOp('Expr_PostDec', $node->var, '--');
Chris@0 406 }
Chris@0 407
Chris@0 408 protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node) {
Chris@0 409 return $this->pPrefixOp('Expr_ErrorSuppress', '@', $node->expr);
Chris@0 410 }
Chris@0 411
Chris@0 412 protected function pExpr_YieldFrom(Expr\YieldFrom $node) {
Chris@0 413 return $this->pPrefixOp('Expr_YieldFrom', 'yield from ', $node->expr);
Chris@0 414 }
Chris@0 415
Chris@0 416 protected function pExpr_Print(Expr\Print_ $node) {
Chris@0 417 return $this->pPrefixOp('Expr_Print', 'print ', $node->expr);
Chris@0 418 }
Chris@0 419
Chris@0 420 // Casts
Chris@0 421
Chris@0 422 protected function pExpr_Cast_Int(Cast\Int_ $node) {
Chris@0 423 return $this->pPrefixOp('Expr_Cast_Int', '(int) ', $node->expr);
Chris@0 424 }
Chris@0 425
Chris@0 426 protected function pExpr_Cast_Double(Cast\Double $node) {
Chris@0 427 return $this->pPrefixOp('Expr_Cast_Double', '(double) ', $node->expr);
Chris@0 428 }
Chris@0 429
Chris@0 430 protected function pExpr_Cast_String(Cast\String_ $node) {
Chris@0 431 return $this->pPrefixOp('Expr_Cast_String', '(string) ', $node->expr);
Chris@0 432 }
Chris@0 433
Chris@0 434 protected function pExpr_Cast_Array(Cast\Array_ $node) {
Chris@0 435 return $this->pPrefixOp('Expr_Cast_Array', '(array) ', $node->expr);
Chris@0 436 }
Chris@0 437
Chris@0 438 protected function pExpr_Cast_Object(Cast\Object_ $node) {
Chris@0 439 return $this->pPrefixOp('Expr_Cast_Object', '(object) ', $node->expr);
Chris@0 440 }
Chris@0 441
Chris@0 442 protected function pExpr_Cast_Bool(Cast\Bool_ $node) {
Chris@0 443 return $this->pPrefixOp('Expr_Cast_Bool', '(bool) ', $node->expr);
Chris@0 444 }
Chris@0 445
Chris@0 446 protected function pExpr_Cast_Unset(Cast\Unset_ $node) {
Chris@0 447 return $this->pPrefixOp('Expr_Cast_Unset', '(unset) ', $node->expr);
Chris@0 448 }
Chris@0 449
Chris@0 450 // Function calls and similar constructs
Chris@0 451
Chris@0 452 protected function pExpr_FuncCall(Expr\FuncCall $node) {
Chris@0 453 return $this->pCallLhs($node->name)
Chris@0 454 . '(' . $this->pMaybeMultiline($node->args) . ')';
Chris@0 455 }
Chris@0 456
Chris@0 457 protected function pExpr_MethodCall(Expr\MethodCall $node) {
Chris@0 458 return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name)
Chris@0 459 . '(' . $this->pMaybeMultiline($node->args) . ')';
Chris@0 460 }
Chris@0 461
Chris@0 462 protected function pExpr_StaticCall(Expr\StaticCall $node) {
Chris@0 463 return $this->pDereferenceLhs($node->class) . '::'
Chris@0 464 . ($node->name instanceof Expr
Chris@0 465 ? ($node->name instanceof Expr\Variable
Chris@0 466 ? $this->p($node->name)
Chris@0 467 : '{' . $this->p($node->name) . '}')
Chris@0 468 : $node->name)
Chris@0 469 . '(' . $this->pMaybeMultiline($node->args) . ')';
Chris@0 470 }
Chris@0 471
Chris@0 472 protected function pExpr_Empty(Expr\Empty_ $node) {
Chris@0 473 return 'empty(' . $this->p($node->expr) . ')';
Chris@0 474 }
Chris@0 475
Chris@0 476 protected function pExpr_Isset(Expr\Isset_ $node) {
Chris@0 477 return 'isset(' . $this->pCommaSeparated($node->vars) . ')';
Chris@0 478 }
Chris@0 479
Chris@0 480 protected function pExpr_Eval(Expr\Eval_ $node) {
Chris@0 481 return 'eval(' . $this->p($node->expr) . ')';
Chris@0 482 }
Chris@0 483
Chris@0 484 protected function pExpr_Include(Expr\Include_ $node) {
Chris@0 485 static $map = array(
Chris@0 486 Expr\Include_::TYPE_INCLUDE => 'include',
Chris@0 487 Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once',
Chris@0 488 Expr\Include_::TYPE_REQUIRE => 'require',
Chris@0 489 Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once',
Chris@0 490 );
Chris@0 491
Chris@0 492 return $map[$node->type] . ' ' . $this->p($node->expr);
Chris@0 493 }
Chris@0 494
Chris@0 495 protected function pExpr_List(Expr\List_ $node) {
Chris@0 496 return 'list(' . $this->pCommaSeparated($node->items) . ')';
Chris@0 497 }
Chris@0 498
Chris@0 499 // Other
Chris@0 500
Chris@0 501 protected function pExpr_Error(Expr\Error $node) {
Chris@0 502 throw new \LogicException('Cannot pretty-print AST with Error nodes');
Chris@0 503 }
Chris@0 504
Chris@0 505 protected function pExpr_Variable(Expr\Variable $node) {
Chris@0 506 if ($node->name instanceof Expr) {
Chris@0 507 return '${' . $this->p($node->name) . '}';
Chris@0 508 } else {
Chris@0 509 return '$' . $node->name;
Chris@0 510 }
Chris@0 511 }
Chris@0 512
Chris@0 513 protected function pExpr_Array(Expr\Array_ $node) {
Chris@0 514 $syntax = $node->getAttribute('kind',
Chris@0 515 $this->options['shortArraySyntax'] ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG);
Chris@0 516 if ($syntax === Expr\Array_::KIND_SHORT) {
Chris@0 517 return '[' . $this->pMaybeMultiline($node->items, true) . ']';
Chris@0 518 } else {
Chris@0 519 return 'array(' . $this->pMaybeMultiline($node->items, true) . ')';
Chris@0 520 }
Chris@0 521 }
Chris@0 522
Chris@0 523 protected function pExpr_ArrayItem(Expr\ArrayItem $node) {
Chris@0 524 return (null !== $node->key ? $this->p($node->key) . ' => ' : '')
Chris@0 525 . ($node->byRef ? '&' : '') . $this->p($node->value);
Chris@0 526 }
Chris@0 527
Chris@0 528 protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node) {
Chris@0 529 return $this->pDereferenceLhs($node->var)
Chris@0 530 . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
Chris@0 531 }
Chris@0 532
Chris@0 533 protected function pExpr_ConstFetch(Expr\ConstFetch $node) {
Chris@0 534 return $this->p($node->name);
Chris@0 535 }
Chris@0 536
Chris@0 537 protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node) {
Chris@0 538 return $this->p($node->class) . '::'
Chris@0 539 . (is_string($node->name) ? $node->name : $this->p($node->name));
Chris@0 540 }
Chris@0 541
Chris@0 542 protected function pExpr_PropertyFetch(Expr\PropertyFetch $node) {
Chris@0 543 return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name);
Chris@0 544 }
Chris@0 545
Chris@0 546 protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node) {
Chris@0 547 return $this->pDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name);
Chris@0 548 }
Chris@0 549
Chris@0 550 protected function pExpr_ShellExec(Expr\ShellExec $node) {
Chris@0 551 return '`' . $this->pEncapsList($node->parts, '`') . '`';
Chris@0 552 }
Chris@0 553
Chris@0 554 protected function pExpr_Closure(Expr\Closure $node) {
Chris@0 555 return ($node->static ? 'static ' : '')
Chris@0 556 . 'function ' . ($node->byRef ? '&' : '')
Chris@0 557 . '(' . $this->pCommaSeparated($node->params) . ')'
Chris@0 558 . (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')': '')
Chris@0 559 . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '')
Chris@0 560 . ' {' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 561 }
Chris@0 562
Chris@0 563 protected function pExpr_ClosureUse(Expr\ClosureUse $node) {
Chris@0 564 return ($node->byRef ? '&' : '') . '$' . $node->var;
Chris@0 565 }
Chris@0 566
Chris@0 567 protected function pExpr_New(Expr\New_ $node) {
Chris@0 568 if ($node->class instanceof Stmt\Class_) {
Chris@0 569 $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : '';
Chris@0 570 return 'new ' . $this->pClassCommon($node->class, $args);
Chris@0 571 }
Chris@0 572 return 'new ' . $this->p($node->class) . '(' . $this->pMaybeMultiline($node->args) . ')';
Chris@0 573 }
Chris@0 574
Chris@0 575 protected function pExpr_Clone(Expr\Clone_ $node) {
Chris@0 576 return 'clone ' . $this->p($node->expr);
Chris@0 577 }
Chris@0 578
Chris@0 579 protected function pExpr_Ternary(Expr\Ternary $node) {
Chris@0 580 // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator.
Chris@0 581 // this is okay because the part between ? and : never needs parentheses.
Chris@0 582 return $this->pInfixOp('Expr_Ternary',
Chris@0 583 $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else
Chris@0 584 );
Chris@0 585 }
Chris@0 586
Chris@0 587 protected function pExpr_Exit(Expr\Exit_ $node) {
Chris@0 588 $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE);
Chris@0 589 return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die')
Chris@0 590 . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : '');
Chris@0 591 }
Chris@0 592
Chris@0 593 protected function pExpr_Yield(Expr\Yield_ $node) {
Chris@0 594 if ($node->value === null) {
Chris@0 595 return 'yield';
Chris@0 596 } else {
Chris@0 597 // this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary
Chris@0 598 return '(yield '
Chris@0 599 . ($node->key !== null ? $this->p($node->key) . ' => ' : '')
Chris@0 600 . $this->p($node->value)
Chris@0 601 . ')';
Chris@0 602 }
Chris@0 603 }
Chris@0 604
Chris@0 605 // Declarations
Chris@0 606
Chris@0 607 protected function pStmt_Namespace(Stmt\Namespace_ $node) {
Chris@0 608 if ($this->canUseSemicolonNamespaces) {
Chris@0 609 return 'namespace ' . $this->p($node->name) . ';' . "\n" . $this->pStmts($node->stmts, false);
Chris@0 610 } else {
Chris@0 611 return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '')
Chris@0 612 . ' {' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 613 }
Chris@0 614 }
Chris@0 615
Chris@0 616 protected function pStmt_Use(Stmt\Use_ $node) {
Chris@0 617 return 'use ' . $this->pUseType($node->type)
Chris@0 618 . $this->pCommaSeparated($node->uses) . ';';
Chris@0 619 }
Chris@0 620
Chris@0 621 protected function pStmt_GroupUse(Stmt\GroupUse $node) {
Chris@0 622 return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix)
Chris@0 623 . '\{' . $this->pCommaSeparated($node->uses) . '};';
Chris@0 624 }
Chris@0 625
Chris@0 626 protected function pStmt_UseUse(Stmt\UseUse $node) {
Chris@0 627 return $this->pUseType($node->type) . $this->p($node->name)
Chris@0 628 . ($node->name->getLast() !== $node->alias ? ' as ' . $node->alias : '');
Chris@0 629 }
Chris@0 630
Chris@0 631 protected function pUseType($type) {
Chris@0 632 return $type === Stmt\Use_::TYPE_FUNCTION ? 'function '
Chris@0 633 : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : '');
Chris@0 634 }
Chris@0 635
Chris@0 636 protected function pStmt_Interface(Stmt\Interface_ $node) {
Chris@0 637 return 'interface ' . $node->name
Chris@0 638 . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '')
Chris@0 639 . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 640 }
Chris@0 641
Chris@0 642 protected function pStmt_Class(Stmt\Class_ $node) {
Chris@0 643 return $this->pClassCommon($node, ' ' . $node->name);
Chris@0 644 }
Chris@0 645
Chris@0 646 protected function pStmt_Trait(Stmt\Trait_ $node) {
Chris@0 647 return 'trait ' . $node->name
Chris@0 648 . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 649 }
Chris@0 650
Chris@0 651 protected function pStmt_TraitUse(Stmt\TraitUse $node) {
Chris@0 652 return 'use ' . $this->pCommaSeparated($node->traits)
Chris@0 653 . (empty($node->adaptations)
Chris@0 654 ? ';'
Chris@0 655 : ' {' . $this->pStmts($node->adaptations) . "\n" . '}');
Chris@0 656 }
Chris@0 657
Chris@0 658 protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node) {
Chris@0 659 return $this->p($node->trait) . '::' . $node->method
Chris@0 660 . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';';
Chris@0 661 }
Chris@0 662
Chris@0 663 protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node) {
Chris@0 664 return (null !== $node->trait ? $this->p($node->trait) . '::' : '')
Chris@0 665 . $node->method . ' as'
Chris@0 666 . (null !== $node->newModifier ? ' ' . rtrim($this->pModifiers($node->newModifier), ' ') : '')
Chris@0 667 . (null !== $node->newName ? ' ' . $node->newName : '')
Chris@0 668 . ';';
Chris@0 669 }
Chris@0 670
Chris@0 671 protected function pStmt_Property(Stmt\Property $node) {
Chris@0 672 return (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) . $this->pCommaSeparated($node->props) . ';';
Chris@0 673 }
Chris@0 674
Chris@0 675 protected function pStmt_PropertyProperty(Stmt\PropertyProperty $node) {
Chris@0 676 return '$' . $node->name
Chris@0 677 . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
Chris@0 678 }
Chris@0 679
Chris@0 680 protected function pStmt_ClassMethod(Stmt\ClassMethod $node) {
Chris@0 681 return $this->pModifiers($node->flags)
Chris@0 682 . 'function ' . ($node->byRef ? '&' : '') . $node->name
Chris@0 683 . '(' . $this->pCommaSeparated($node->params) . ')'
Chris@0 684 . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '')
Chris@0 685 . (null !== $node->stmts
Chris@0 686 ? "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'
Chris@0 687 : ';');
Chris@0 688 }
Chris@0 689
Chris@0 690 protected function pStmt_ClassConst(Stmt\ClassConst $node) {
Chris@0 691 return $this->pModifiers($node->flags)
Chris@0 692 . 'const ' . $this->pCommaSeparated($node->consts) . ';';
Chris@0 693 }
Chris@0 694
Chris@0 695 protected function pStmt_Function(Stmt\Function_ $node) {
Chris@0 696 return 'function ' . ($node->byRef ? '&' : '') . $node->name
Chris@0 697 . '(' . $this->pCommaSeparated($node->params) . ')'
Chris@0 698 . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '')
Chris@0 699 . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 700 }
Chris@0 701
Chris@0 702 protected function pStmt_Const(Stmt\Const_ $node) {
Chris@0 703 return 'const ' . $this->pCommaSeparated($node->consts) . ';';
Chris@0 704 }
Chris@0 705
Chris@0 706 protected function pStmt_Declare(Stmt\Declare_ $node) {
Chris@0 707 return 'declare (' . $this->pCommaSeparated($node->declares) . ')'
Chris@0 708 . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . "\n" . '}' : ';');
Chris@0 709 }
Chris@0 710
Chris@0 711 protected function pStmt_DeclareDeclare(Stmt\DeclareDeclare $node) {
Chris@0 712 return $node->key . '=' . $this->p($node->value);
Chris@0 713 }
Chris@0 714
Chris@0 715 // Control flow
Chris@0 716
Chris@0 717 protected function pStmt_If(Stmt\If_ $node) {
Chris@0 718 return 'if (' . $this->p($node->cond) . ') {'
Chris@0 719 . $this->pStmts($node->stmts) . "\n" . '}'
Chris@0 720 . $this->pImplode($node->elseifs)
Chris@0 721 . (null !== $node->else ? $this->p($node->else) : '');
Chris@0 722 }
Chris@0 723
Chris@0 724 protected function pStmt_ElseIf(Stmt\ElseIf_ $node) {
Chris@0 725 return ' elseif (' . $this->p($node->cond) . ') {'
Chris@0 726 . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 727 }
Chris@0 728
Chris@0 729 protected function pStmt_Else(Stmt\Else_ $node) {
Chris@0 730 return ' else {' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 731 }
Chris@0 732
Chris@0 733 protected function pStmt_For(Stmt\For_ $node) {
Chris@0 734 return 'for ('
Chris@0 735 . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '')
Chris@0 736 . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '')
Chris@0 737 . $this->pCommaSeparated($node->loop)
Chris@0 738 . ') {' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 739 }
Chris@0 740
Chris@0 741 protected function pStmt_Foreach(Stmt\Foreach_ $node) {
Chris@0 742 return 'foreach (' . $this->p($node->expr) . ' as '
Chris@0 743 . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '')
Chris@0 744 . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {'
Chris@0 745 . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 746 }
Chris@0 747
Chris@0 748 protected function pStmt_While(Stmt\While_ $node) {
Chris@0 749 return 'while (' . $this->p($node->cond) . ') {'
Chris@0 750 . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 751 }
Chris@0 752
Chris@0 753 protected function pStmt_Do(Stmt\Do_ $node) {
Chris@0 754 return 'do {' . $this->pStmts($node->stmts) . "\n"
Chris@0 755 . '} while (' . $this->p($node->cond) . ');';
Chris@0 756 }
Chris@0 757
Chris@0 758 protected function pStmt_Switch(Stmt\Switch_ $node) {
Chris@0 759 return 'switch (' . $this->p($node->cond) . ') {'
Chris@0 760 . $this->pStmts($node->cases) . "\n" . '}';
Chris@0 761 }
Chris@0 762
Chris@0 763 protected function pStmt_Case(Stmt\Case_ $node) {
Chris@0 764 return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':'
Chris@0 765 . $this->pStmts($node->stmts);
Chris@0 766 }
Chris@0 767
Chris@0 768 protected function pStmt_TryCatch(Stmt\TryCatch $node) {
Chris@0 769 return 'try {' . $this->pStmts($node->stmts) . "\n" . '}'
Chris@0 770 . $this->pImplode($node->catches)
Chris@0 771 . ($node->finally !== null ? $this->p($node->finally) : '');
Chris@0 772 }
Chris@0 773
Chris@0 774 protected function pStmt_Catch(Stmt\Catch_ $node) {
Chris@0 775 return ' catch (' . $this->pImplode($node->types, '|') . ' $' . $node->var . ') {'
Chris@0 776 . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 777 }
Chris@0 778
Chris@0 779 protected function pStmt_Finally(Stmt\Finally_ $node) {
Chris@0 780 return ' finally {' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 781 }
Chris@0 782
Chris@0 783 protected function pStmt_Break(Stmt\Break_ $node) {
Chris@0 784 return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
Chris@0 785 }
Chris@0 786
Chris@0 787 protected function pStmt_Continue(Stmt\Continue_ $node) {
Chris@0 788 return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
Chris@0 789 }
Chris@0 790
Chris@0 791 protected function pStmt_Return(Stmt\Return_ $node) {
Chris@0 792 return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';';
Chris@0 793 }
Chris@0 794
Chris@0 795 protected function pStmt_Throw(Stmt\Throw_ $node) {
Chris@0 796 return 'throw ' . $this->p($node->expr) . ';';
Chris@0 797 }
Chris@0 798
Chris@0 799 protected function pStmt_Label(Stmt\Label $node) {
Chris@0 800 return $node->name . ':';
Chris@0 801 }
Chris@0 802
Chris@0 803 protected function pStmt_Goto(Stmt\Goto_ $node) {
Chris@0 804 return 'goto ' . $node->name . ';';
Chris@0 805 }
Chris@0 806
Chris@0 807 // Other
Chris@0 808
Chris@0 809 protected function pStmt_Echo(Stmt\Echo_ $node) {
Chris@0 810 return 'echo ' . $this->pCommaSeparated($node->exprs) . ';';
Chris@0 811 }
Chris@0 812
Chris@0 813 protected function pStmt_Static(Stmt\Static_ $node) {
Chris@0 814 return 'static ' . $this->pCommaSeparated($node->vars) . ';';
Chris@0 815 }
Chris@0 816
Chris@0 817 protected function pStmt_Global(Stmt\Global_ $node) {
Chris@0 818 return 'global ' . $this->pCommaSeparated($node->vars) . ';';
Chris@0 819 }
Chris@0 820
Chris@0 821 protected function pStmt_StaticVar(Stmt\StaticVar $node) {
Chris@0 822 return '$' . $node->name
Chris@0 823 . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
Chris@0 824 }
Chris@0 825
Chris@0 826 protected function pStmt_Unset(Stmt\Unset_ $node) {
Chris@0 827 return 'unset(' . $this->pCommaSeparated($node->vars) . ');';
Chris@0 828 }
Chris@0 829
Chris@0 830 protected function pStmt_InlineHTML(Stmt\InlineHTML $node) {
Chris@0 831 $newline = $node->getAttribute('hasLeadingNewline', true) ? "\n" : '';
Chris@0 832 return '?>' . $this->pNoIndent($newline . $node->value) . '<?php ';
Chris@0 833 }
Chris@0 834
Chris@0 835 protected function pStmt_HaltCompiler(Stmt\HaltCompiler $node) {
Chris@0 836 return '__halt_compiler();' . $node->remaining;
Chris@0 837 }
Chris@0 838
Chris@0 839 protected function pStmt_Nop(Stmt\Nop $node) {
Chris@0 840 return '';
Chris@0 841 }
Chris@0 842
Chris@0 843 // Helpers
Chris@0 844
Chris@0 845 protected function pType($node) {
Chris@0 846 return is_string($node) ? $node : $this->p($node);
Chris@0 847 }
Chris@0 848
Chris@0 849 protected function pClassCommon(Stmt\Class_ $node, $afterClassToken) {
Chris@0 850 return $this->pModifiers($node->flags)
Chris@0 851 . 'class' . $afterClassToken
Chris@0 852 . (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '')
Chris@0 853 . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '')
Chris@0 854 . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 855 }
Chris@0 856
Chris@0 857 protected function pObjectProperty($node) {
Chris@0 858 if ($node instanceof Expr) {
Chris@0 859 return '{' . $this->p($node) . '}';
Chris@0 860 } else {
Chris@0 861 return $node;
Chris@0 862 }
Chris@0 863 }
Chris@0 864
Chris@0 865 protected function pModifiers($modifiers) {
Chris@0 866 return ($modifiers & Stmt\Class_::MODIFIER_PUBLIC ? 'public ' : '')
Chris@0 867 . ($modifiers & Stmt\Class_::MODIFIER_PROTECTED ? 'protected ' : '')
Chris@0 868 . ($modifiers & Stmt\Class_::MODIFIER_PRIVATE ? 'private ' : '')
Chris@0 869 . ($modifiers & Stmt\Class_::MODIFIER_STATIC ? 'static ' : '')
Chris@0 870 . ($modifiers & Stmt\Class_::MODIFIER_ABSTRACT ? 'abstract ' : '')
Chris@0 871 . ($modifiers & Stmt\Class_::MODIFIER_FINAL ? 'final ' : '');
Chris@0 872 }
Chris@0 873
Chris@0 874 protected function pEncapsList(array $encapsList, $quote) {
Chris@0 875 $return = '';
Chris@0 876 foreach ($encapsList as $element) {
Chris@0 877 if ($element instanceof Scalar\EncapsedStringPart) {
Chris@0 878 $return .= $this->escapeString($element->value, $quote);
Chris@0 879 } else {
Chris@0 880 $return .= '{' . $this->p($element) . '}';
Chris@0 881 }
Chris@0 882 }
Chris@0 883
Chris@0 884 return $return;
Chris@0 885 }
Chris@0 886
Chris@0 887 protected function escapeString($string, $quote) {
Chris@0 888 if (null === $quote) {
Chris@0 889 // For doc strings, don't escape newlines
Chris@0 890 $escaped = addcslashes($string, "\t\f\v$\\");
Chris@0 891 } else {
Chris@0 892 $escaped = addcslashes($string, "\n\r\t\f\v$" . $quote . "\\");
Chris@0 893 }
Chris@0 894
Chris@0 895 // Escape other control characters
Chris@0 896 return preg_replace_callback('/([\0-\10\16-\37])(?=([0-7]?))/', function ($matches) {
Chris@0 897 $oct = decoct(ord($matches[1]));
Chris@0 898 if ($matches[2] !== '') {
Chris@0 899 // If there is a trailing digit, use the full three character form
Chris@0 900 return '\\' . str_pad($oct, 3, '0', STR_PAD_LEFT);
Chris@0 901 }
Chris@0 902 return '\\' . $oct;
Chris@0 903 }, $escaped);
Chris@0 904 }
Chris@0 905
Chris@0 906 protected function containsEndLabel($string, $label, $atStart = true, $atEnd = true) {
Chris@0 907 $start = $atStart ? '(?:^|[\r\n])' : '[\r\n]';
Chris@0 908 $end = $atEnd ? '(?:$|[;\r\n])' : '[;\r\n]';
Chris@0 909 return false !== strpos($string, $label)
Chris@0 910 && preg_match('/' . $start . $label . $end . '/', $string);
Chris@0 911 }
Chris@0 912
Chris@0 913 protected function encapsedContainsEndLabel(array $parts, $label) {
Chris@0 914 foreach ($parts as $i => $part) {
Chris@0 915 $atStart = $i === 0;
Chris@0 916 $atEnd = $i === count($parts) - 1;
Chris@0 917 if ($part instanceof Scalar\EncapsedStringPart
Chris@0 918 && $this->containsEndLabel($part->value, $label, $atStart, $atEnd)
Chris@0 919 ) {
Chris@0 920 return true;
Chris@0 921 }
Chris@0 922 }
Chris@0 923 return false;
Chris@0 924 }
Chris@0 925
Chris@0 926 protected function pDereferenceLhs(Node $node) {
Chris@0 927 if ($node instanceof Expr\Variable
Chris@0 928 || $node instanceof Name
Chris@0 929 || $node instanceof Expr\ArrayDimFetch
Chris@0 930 || $node instanceof Expr\PropertyFetch
Chris@0 931 || $node instanceof Expr\StaticPropertyFetch
Chris@0 932 || $node instanceof Expr\FuncCall
Chris@0 933 || $node instanceof Expr\MethodCall
Chris@0 934 || $node instanceof Expr\StaticCall
Chris@0 935 || $node instanceof Expr\Array_
Chris@0 936 || $node instanceof Scalar\String_
Chris@0 937 || $node instanceof Expr\ConstFetch
Chris@0 938 || $node instanceof Expr\ClassConstFetch
Chris@0 939 ) {
Chris@0 940 return $this->p($node);
Chris@0 941 } else {
Chris@0 942 return '(' . $this->p($node) . ')';
Chris@0 943 }
Chris@0 944 }
Chris@0 945
Chris@0 946 protected function pCallLhs(Node $node) {
Chris@0 947 if ($node instanceof Name
Chris@0 948 || $node instanceof Expr\Variable
Chris@0 949 || $node instanceof Expr\ArrayDimFetch
Chris@0 950 || $node instanceof Expr\FuncCall
Chris@0 951 || $node instanceof Expr\MethodCall
Chris@0 952 || $node instanceof Expr\StaticCall
Chris@0 953 || $node instanceof Expr\Array_
Chris@0 954 ) {
Chris@0 955 return $this->p($node);
Chris@0 956 } else {
Chris@0 957 return '(' . $this->p($node) . ')';
Chris@0 958 }
Chris@0 959 }
Chris@0 960
Chris@0 961 private function hasNodeWithComments(array $nodes) {
Chris@0 962 foreach ($nodes as $node) {
Chris@0 963 if ($node && $node->getAttribute('comments')) {
Chris@0 964 return true;
Chris@0 965 }
Chris@0 966 }
Chris@0 967 return false;
Chris@0 968 }
Chris@0 969
Chris@0 970 private function pMaybeMultiline(array $nodes, $trailingComma = false) {
Chris@0 971 if (!$this->hasNodeWithComments($nodes)) {
Chris@0 972 return $this->pCommaSeparated($nodes);
Chris@0 973 } else {
Chris@0 974 return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . "\n";
Chris@0 975 }
Chris@0 976 }
Chris@0 977 }