annotate vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php @ 13:5fb285c0d0e3

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