annotate vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php @ 2:92f882872392

Trusted hosts, + remove migration modules
author Chris Cannam
date Tue, 05 Dec 2017 09:26:43 +0000
parents 4c8ae668cc8c
children 7a779792577d
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@0 377 return $this->pPrefixOp('Expr_UnaryMinus', '-', $node->expr);
Chris@0 378 }
Chris@0 379
Chris@0 380 protected function pExpr_UnaryPlus(Expr\UnaryPlus $node) {
Chris@0 381 return $this->pPrefixOp('Expr_UnaryPlus', '+', $node->expr);
Chris@0 382 }
Chris@0 383
Chris@0 384 protected function pExpr_PreInc(Expr\PreInc $node) {
Chris@0 385 return $this->pPrefixOp('Expr_PreInc', '++', $node->var);
Chris@0 386 }
Chris@0 387
Chris@0 388 protected function pExpr_PreDec(Expr\PreDec $node) {
Chris@0 389 return $this->pPrefixOp('Expr_PreDec', '--', $node->var);
Chris@0 390 }
Chris@0 391
Chris@0 392 protected function pExpr_PostInc(Expr\PostInc $node) {
Chris@0 393 return $this->pPostfixOp('Expr_PostInc', $node->var, '++');
Chris@0 394 }
Chris@0 395
Chris@0 396 protected function pExpr_PostDec(Expr\PostDec $node) {
Chris@0 397 return $this->pPostfixOp('Expr_PostDec', $node->var, '--');
Chris@0 398 }
Chris@0 399
Chris@0 400 protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node) {
Chris@0 401 return $this->pPrefixOp('Expr_ErrorSuppress', '@', $node->expr);
Chris@0 402 }
Chris@0 403
Chris@0 404 protected function pExpr_YieldFrom(Expr\YieldFrom $node) {
Chris@0 405 return $this->pPrefixOp('Expr_YieldFrom', 'yield from ', $node->expr);
Chris@0 406 }
Chris@0 407
Chris@0 408 protected function pExpr_Print(Expr\Print_ $node) {
Chris@0 409 return $this->pPrefixOp('Expr_Print', 'print ', $node->expr);
Chris@0 410 }
Chris@0 411
Chris@0 412 // Casts
Chris@0 413
Chris@0 414 protected function pExpr_Cast_Int(Cast\Int_ $node) {
Chris@0 415 return $this->pPrefixOp('Expr_Cast_Int', '(int) ', $node->expr);
Chris@0 416 }
Chris@0 417
Chris@0 418 protected function pExpr_Cast_Double(Cast\Double $node) {
Chris@0 419 return $this->pPrefixOp('Expr_Cast_Double', '(double) ', $node->expr);
Chris@0 420 }
Chris@0 421
Chris@0 422 protected function pExpr_Cast_String(Cast\String_ $node) {
Chris@0 423 return $this->pPrefixOp('Expr_Cast_String', '(string) ', $node->expr);
Chris@0 424 }
Chris@0 425
Chris@0 426 protected function pExpr_Cast_Array(Cast\Array_ $node) {
Chris@0 427 return $this->pPrefixOp('Expr_Cast_Array', '(array) ', $node->expr);
Chris@0 428 }
Chris@0 429
Chris@0 430 protected function pExpr_Cast_Object(Cast\Object_ $node) {
Chris@0 431 return $this->pPrefixOp('Expr_Cast_Object', '(object) ', $node->expr);
Chris@0 432 }
Chris@0 433
Chris@0 434 protected function pExpr_Cast_Bool(Cast\Bool_ $node) {
Chris@0 435 return $this->pPrefixOp('Expr_Cast_Bool', '(bool) ', $node->expr);
Chris@0 436 }
Chris@0 437
Chris@0 438 protected function pExpr_Cast_Unset(Cast\Unset_ $node) {
Chris@0 439 return $this->pPrefixOp('Expr_Cast_Unset', '(unset) ', $node->expr);
Chris@0 440 }
Chris@0 441
Chris@0 442 // Function calls and similar constructs
Chris@0 443
Chris@0 444 protected function pExpr_FuncCall(Expr\FuncCall $node) {
Chris@0 445 return $this->pCallLhs($node->name)
Chris@0 446 . '(' . $this->pMaybeMultiline($node->args) . ')';
Chris@0 447 }
Chris@0 448
Chris@0 449 protected function pExpr_MethodCall(Expr\MethodCall $node) {
Chris@0 450 return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name)
Chris@0 451 . '(' . $this->pMaybeMultiline($node->args) . ')';
Chris@0 452 }
Chris@0 453
Chris@0 454 protected function pExpr_StaticCall(Expr\StaticCall $node) {
Chris@0 455 return $this->pDereferenceLhs($node->class) . '::'
Chris@0 456 . ($node->name instanceof Expr
Chris@0 457 ? ($node->name instanceof Expr\Variable
Chris@0 458 ? $this->p($node->name)
Chris@0 459 : '{' . $this->p($node->name) . '}')
Chris@0 460 : $node->name)
Chris@0 461 . '(' . $this->pMaybeMultiline($node->args) . ')';
Chris@0 462 }
Chris@0 463
Chris@0 464 protected function pExpr_Empty(Expr\Empty_ $node) {
Chris@0 465 return 'empty(' . $this->p($node->expr) . ')';
Chris@0 466 }
Chris@0 467
Chris@0 468 protected function pExpr_Isset(Expr\Isset_ $node) {
Chris@0 469 return 'isset(' . $this->pCommaSeparated($node->vars) . ')';
Chris@0 470 }
Chris@0 471
Chris@0 472 protected function pExpr_Eval(Expr\Eval_ $node) {
Chris@0 473 return 'eval(' . $this->p($node->expr) . ')';
Chris@0 474 }
Chris@0 475
Chris@0 476 protected function pExpr_Include(Expr\Include_ $node) {
Chris@0 477 static $map = array(
Chris@0 478 Expr\Include_::TYPE_INCLUDE => 'include',
Chris@0 479 Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once',
Chris@0 480 Expr\Include_::TYPE_REQUIRE => 'require',
Chris@0 481 Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once',
Chris@0 482 );
Chris@0 483
Chris@0 484 return $map[$node->type] . ' ' . $this->p($node->expr);
Chris@0 485 }
Chris@0 486
Chris@0 487 protected function pExpr_List(Expr\List_ $node) {
Chris@0 488 return 'list(' . $this->pCommaSeparated($node->items) . ')';
Chris@0 489 }
Chris@0 490
Chris@0 491 // Other
Chris@0 492
Chris@0 493 protected function pExpr_Error(Expr\Error $node) {
Chris@0 494 throw new \LogicException('Cannot pretty-print AST with Error nodes');
Chris@0 495 }
Chris@0 496
Chris@0 497 protected function pExpr_Variable(Expr\Variable $node) {
Chris@0 498 if ($node->name instanceof Expr) {
Chris@0 499 return '${' . $this->p($node->name) . '}';
Chris@0 500 } else {
Chris@0 501 return '$' . $node->name;
Chris@0 502 }
Chris@0 503 }
Chris@0 504
Chris@0 505 protected function pExpr_Array(Expr\Array_ $node) {
Chris@0 506 $syntax = $node->getAttribute('kind',
Chris@0 507 $this->options['shortArraySyntax'] ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG);
Chris@0 508 if ($syntax === Expr\Array_::KIND_SHORT) {
Chris@0 509 return '[' . $this->pMaybeMultiline($node->items, true) . ']';
Chris@0 510 } else {
Chris@0 511 return 'array(' . $this->pMaybeMultiline($node->items, true) . ')';
Chris@0 512 }
Chris@0 513 }
Chris@0 514
Chris@0 515 protected function pExpr_ArrayItem(Expr\ArrayItem $node) {
Chris@0 516 return (null !== $node->key ? $this->p($node->key) . ' => ' : '')
Chris@0 517 . ($node->byRef ? '&' : '') . $this->p($node->value);
Chris@0 518 }
Chris@0 519
Chris@0 520 protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node) {
Chris@0 521 return $this->pDereferenceLhs($node->var)
Chris@0 522 . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
Chris@0 523 }
Chris@0 524
Chris@0 525 protected function pExpr_ConstFetch(Expr\ConstFetch $node) {
Chris@0 526 return $this->p($node->name);
Chris@0 527 }
Chris@0 528
Chris@0 529 protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node) {
Chris@0 530 return $this->p($node->class) . '::'
Chris@0 531 . (is_string($node->name) ? $node->name : $this->p($node->name));
Chris@0 532 }
Chris@0 533
Chris@0 534 protected function pExpr_PropertyFetch(Expr\PropertyFetch $node) {
Chris@0 535 return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name);
Chris@0 536 }
Chris@0 537
Chris@0 538 protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node) {
Chris@0 539 return $this->pDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name);
Chris@0 540 }
Chris@0 541
Chris@0 542 protected function pExpr_ShellExec(Expr\ShellExec $node) {
Chris@0 543 return '`' . $this->pEncapsList($node->parts, '`') . '`';
Chris@0 544 }
Chris@0 545
Chris@0 546 protected function pExpr_Closure(Expr\Closure $node) {
Chris@0 547 return ($node->static ? 'static ' : '')
Chris@0 548 . 'function ' . ($node->byRef ? '&' : '')
Chris@0 549 . '(' . $this->pCommaSeparated($node->params) . ')'
Chris@0 550 . (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')': '')
Chris@0 551 . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '')
Chris@0 552 . ' {' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 553 }
Chris@0 554
Chris@0 555 protected function pExpr_ClosureUse(Expr\ClosureUse $node) {
Chris@0 556 return ($node->byRef ? '&' : '') . '$' . $node->var;
Chris@0 557 }
Chris@0 558
Chris@0 559 protected function pExpr_New(Expr\New_ $node) {
Chris@0 560 if ($node->class instanceof Stmt\Class_) {
Chris@0 561 $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : '';
Chris@0 562 return 'new ' . $this->pClassCommon($node->class, $args);
Chris@0 563 }
Chris@0 564 return 'new ' . $this->p($node->class) . '(' . $this->pMaybeMultiline($node->args) . ')';
Chris@0 565 }
Chris@0 566
Chris@0 567 protected function pExpr_Clone(Expr\Clone_ $node) {
Chris@0 568 return 'clone ' . $this->p($node->expr);
Chris@0 569 }
Chris@0 570
Chris@0 571 protected function pExpr_Ternary(Expr\Ternary $node) {
Chris@0 572 // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator.
Chris@0 573 // this is okay because the part between ? and : never needs parentheses.
Chris@0 574 return $this->pInfixOp('Expr_Ternary',
Chris@0 575 $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else
Chris@0 576 );
Chris@0 577 }
Chris@0 578
Chris@0 579 protected function pExpr_Exit(Expr\Exit_ $node) {
Chris@0 580 $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE);
Chris@0 581 return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die')
Chris@0 582 . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : '');
Chris@0 583 }
Chris@0 584
Chris@0 585 protected function pExpr_Yield(Expr\Yield_ $node) {
Chris@0 586 if ($node->value === null) {
Chris@0 587 return 'yield';
Chris@0 588 } else {
Chris@0 589 // this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary
Chris@0 590 return '(yield '
Chris@0 591 . ($node->key !== null ? $this->p($node->key) . ' => ' : '')
Chris@0 592 . $this->p($node->value)
Chris@0 593 . ')';
Chris@0 594 }
Chris@0 595 }
Chris@0 596
Chris@0 597 // Declarations
Chris@0 598
Chris@0 599 protected function pStmt_Namespace(Stmt\Namespace_ $node) {
Chris@0 600 if ($this->canUseSemicolonNamespaces) {
Chris@0 601 return 'namespace ' . $this->p($node->name) . ';' . "\n" . $this->pStmts($node->stmts, false);
Chris@0 602 } else {
Chris@0 603 return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '')
Chris@0 604 . ' {' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 605 }
Chris@0 606 }
Chris@0 607
Chris@0 608 protected function pStmt_Use(Stmt\Use_ $node) {
Chris@0 609 return 'use ' . $this->pUseType($node->type)
Chris@0 610 . $this->pCommaSeparated($node->uses) . ';';
Chris@0 611 }
Chris@0 612
Chris@0 613 protected function pStmt_GroupUse(Stmt\GroupUse $node) {
Chris@0 614 return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix)
Chris@0 615 . '\{' . $this->pCommaSeparated($node->uses) . '};';
Chris@0 616 }
Chris@0 617
Chris@0 618 protected function pStmt_UseUse(Stmt\UseUse $node) {
Chris@0 619 return $this->pUseType($node->type) . $this->p($node->name)
Chris@0 620 . ($node->name->getLast() !== $node->alias ? ' as ' . $node->alias : '');
Chris@0 621 }
Chris@0 622
Chris@0 623 protected function pUseType($type) {
Chris@0 624 return $type === Stmt\Use_::TYPE_FUNCTION ? 'function '
Chris@0 625 : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : '');
Chris@0 626 }
Chris@0 627
Chris@0 628 protected function pStmt_Interface(Stmt\Interface_ $node) {
Chris@0 629 return 'interface ' . $node->name
Chris@0 630 . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '')
Chris@0 631 . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 632 }
Chris@0 633
Chris@0 634 protected function pStmt_Class(Stmt\Class_ $node) {
Chris@0 635 return $this->pClassCommon($node, ' ' . $node->name);
Chris@0 636 }
Chris@0 637
Chris@0 638 protected function pStmt_Trait(Stmt\Trait_ $node) {
Chris@0 639 return 'trait ' . $node->name
Chris@0 640 . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 641 }
Chris@0 642
Chris@0 643 protected function pStmt_TraitUse(Stmt\TraitUse $node) {
Chris@0 644 return 'use ' . $this->pCommaSeparated($node->traits)
Chris@0 645 . (empty($node->adaptations)
Chris@0 646 ? ';'
Chris@0 647 : ' {' . $this->pStmts($node->adaptations) . "\n" . '}');
Chris@0 648 }
Chris@0 649
Chris@0 650 protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node) {
Chris@0 651 return $this->p($node->trait) . '::' . $node->method
Chris@0 652 . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';';
Chris@0 653 }
Chris@0 654
Chris@0 655 protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node) {
Chris@0 656 return (null !== $node->trait ? $this->p($node->trait) . '::' : '')
Chris@0 657 . $node->method . ' as'
Chris@0 658 . (null !== $node->newModifier ? ' ' . rtrim($this->pModifiers($node->newModifier), ' ') : '')
Chris@0 659 . (null !== $node->newName ? ' ' . $node->newName : '')
Chris@0 660 . ';';
Chris@0 661 }
Chris@0 662
Chris@0 663 protected function pStmt_Property(Stmt\Property $node) {
Chris@0 664 return (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) . $this->pCommaSeparated($node->props) . ';';
Chris@0 665 }
Chris@0 666
Chris@0 667 protected function pStmt_PropertyProperty(Stmt\PropertyProperty $node) {
Chris@0 668 return '$' . $node->name
Chris@0 669 . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
Chris@0 670 }
Chris@0 671
Chris@0 672 protected function pStmt_ClassMethod(Stmt\ClassMethod $node) {
Chris@0 673 return $this->pModifiers($node->flags)
Chris@0 674 . 'function ' . ($node->byRef ? '&' : '') . $node->name
Chris@0 675 . '(' . $this->pCommaSeparated($node->params) . ')'
Chris@0 676 . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '')
Chris@0 677 . (null !== $node->stmts
Chris@0 678 ? "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'
Chris@0 679 : ';');
Chris@0 680 }
Chris@0 681
Chris@0 682 protected function pStmt_ClassConst(Stmt\ClassConst $node) {
Chris@0 683 return $this->pModifiers($node->flags)
Chris@0 684 . 'const ' . $this->pCommaSeparated($node->consts) . ';';
Chris@0 685 }
Chris@0 686
Chris@0 687 protected function pStmt_Function(Stmt\Function_ $node) {
Chris@0 688 return 'function ' . ($node->byRef ? '&' : '') . $node->name
Chris@0 689 . '(' . $this->pCommaSeparated($node->params) . ')'
Chris@0 690 . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '')
Chris@0 691 . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 692 }
Chris@0 693
Chris@0 694 protected function pStmt_Const(Stmt\Const_ $node) {
Chris@0 695 return 'const ' . $this->pCommaSeparated($node->consts) . ';';
Chris@0 696 }
Chris@0 697
Chris@0 698 protected function pStmt_Declare(Stmt\Declare_ $node) {
Chris@0 699 return 'declare (' . $this->pCommaSeparated($node->declares) . ')'
Chris@0 700 . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . "\n" . '}' : ';');
Chris@0 701 }
Chris@0 702
Chris@0 703 protected function pStmt_DeclareDeclare(Stmt\DeclareDeclare $node) {
Chris@0 704 return $node->key . '=' . $this->p($node->value);
Chris@0 705 }
Chris@0 706
Chris@0 707 // Control flow
Chris@0 708
Chris@0 709 protected function pStmt_If(Stmt\If_ $node) {
Chris@0 710 return 'if (' . $this->p($node->cond) . ') {'
Chris@0 711 . $this->pStmts($node->stmts) . "\n" . '}'
Chris@0 712 . $this->pImplode($node->elseifs)
Chris@0 713 . (null !== $node->else ? $this->p($node->else) : '');
Chris@0 714 }
Chris@0 715
Chris@0 716 protected function pStmt_ElseIf(Stmt\ElseIf_ $node) {
Chris@0 717 return ' elseif (' . $this->p($node->cond) . ') {'
Chris@0 718 . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 719 }
Chris@0 720
Chris@0 721 protected function pStmt_Else(Stmt\Else_ $node) {
Chris@0 722 return ' else {' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 723 }
Chris@0 724
Chris@0 725 protected function pStmt_For(Stmt\For_ $node) {
Chris@0 726 return 'for ('
Chris@0 727 . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '')
Chris@0 728 . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '')
Chris@0 729 . $this->pCommaSeparated($node->loop)
Chris@0 730 . ') {' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 731 }
Chris@0 732
Chris@0 733 protected function pStmt_Foreach(Stmt\Foreach_ $node) {
Chris@0 734 return 'foreach (' . $this->p($node->expr) . ' as '
Chris@0 735 . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '')
Chris@0 736 . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {'
Chris@0 737 . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 738 }
Chris@0 739
Chris@0 740 protected function pStmt_While(Stmt\While_ $node) {
Chris@0 741 return 'while (' . $this->p($node->cond) . ') {'
Chris@0 742 . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 743 }
Chris@0 744
Chris@0 745 protected function pStmt_Do(Stmt\Do_ $node) {
Chris@0 746 return 'do {' . $this->pStmts($node->stmts) . "\n"
Chris@0 747 . '} while (' . $this->p($node->cond) . ');';
Chris@0 748 }
Chris@0 749
Chris@0 750 protected function pStmt_Switch(Stmt\Switch_ $node) {
Chris@0 751 return 'switch (' . $this->p($node->cond) . ') {'
Chris@0 752 . $this->pStmts($node->cases) . "\n" . '}';
Chris@0 753 }
Chris@0 754
Chris@0 755 protected function pStmt_Case(Stmt\Case_ $node) {
Chris@0 756 return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':'
Chris@0 757 . $this->pStmts($node->stmts);
Chris@0 758 }
Chris@0 759
Chris@0 760 protected function pStmt_TryCatch(Stmt\TryCatch $node) {
Chris@0 761 return 'try {' . $this->pStmts($node->stmts) . "\n" . '}'
Chris@0 762 . $this->pImplode($node->catches)
Chris@0 763 . ($node->finally !== null ? $this->p($node->finally) : '');
Chris@0 764 }
Chris@0 765
Chris@0 766 protected function pStmt_Catch(Stmt\Catch_ $node) {
Chris@0 767 return ' catch (' . $this->pImplode($node->types, '|') . ' $' . $node->var . ') {'
Chris@0 768 . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 769 }
Chris@0 770
Chris@0 771 protected function pStmt_Finally(Stmt\Finally_ $node) {
Chris@0 772 return ' finally {' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 773 }
Chris@0 774
Chris@0 775 protected function pStmt_Break(Stmt\Break_ $node) {
Chris@0 776 return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
Chris@0 777 }
Chris@0 778
Chris@0 779 protected function pStmt_Continue(Stmt\Continue_ $node) {
Chris@0 780 return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
Chris@0 781 }
Chris@0 782
Chris@0 783 protected function pStmt_Return(Stmt\Return_ $node) {
Chris@0 784 return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';';
Chris@0 785 }
Chris@0 786
Chris@0 787 protected function pStmt_Throw(Stmt\Throw_ $node) {
Chris@0 788 return 'throw ' . $this->p($node->expr) . ';';
Chris@0 789 }
Chris@0 790
Chris@0 791 protected function pStmt_Label(Stmt\Label $node) {
Chris@0 792 return $node->name . ':';
Chris@0 793 }
Chris@0 794
Chris@0 795 protected function pStmt_Goto(Stmt\Goto_ $node) {
Chris@0 796 return 'goto ' . $node->name . ';';
Chris@0 797 }
Chris@0 798
Chris@0 799 // Other
Chris@0 800
Chris@0 801 protected function pStmt_Echo(Stmt\Echo_ $node) {
Chris@0 802 return 'echo ' . $this->pCommaSeparated($node->exprs) . ';';
Chris@0 803 }
Chris@0 804
Chris@0 805 protected function pStmt_Static(Stmt\Static_ $node) {
Chris@0 806 return 'static ' . $this->pCommaSeparated($node->vars) . ';';
Chris@0 807 }
Chris@0 808
Chris@0 809 protected function pStmt_Global(Stmt\Global_ $node) {
Chris@0 810 return 'global ' . $this->pCommaSeparated($node->vars) . ';';
Chris@0 811 }
Chris@0 812
Chris@0 813 protected function pStmt_StaticVar(Stmt\StaticVar $node) {
Chris@0 814 return '$' . $node->name
Chris@0 815 . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
Chris@0 816 }
Chris@0 817
Chris@0 818 protected function pStmt_Unset(Stmt\Unset_ $node) {
Chris@0 819 return 'unset(' . $this->pCommaSeparated($node->vars) . ');';
Chris@0 820 }
Chris@0 821
Chris@0 822 protected function pStmt_InlineHTML(Stmt\InlineHTML $node) {
Chris@0 823 $newline = $node->getAttribute('hasLeadingNewline', true) ? "\n" : '';
Chris@0 824 return '?>' . $this->pNoIndent($newline . $node->value) . '<?php ';
Chris@0 825 }
Chris@0 826
Chris@0 827 protected function pStmt_HaltCompiler(Stmt\HaltCompiler $node) {
Chris@0 828 return '__halt_compiler();' . $node->remaining;
Chris@0 829 }
Chris@0 830
Chris@0 831 protected function pStmt_Nop(Stmt\Nop $node) {
Chris@0 832 return '';
Chris@0 833 }
Chris@0 834
Chris@0 835 // Helpers
Chris@0 836
Chris@0 837 protected function pType($node) {
Chris@0 838 return is_string($node) ? $node : $this->p($node);
Chris@0 839 }
Chris@0 840
Chris@0 841 protected function pClassCommon(Stmt\Class_ $node, $afterClassToken) {
Chris@0 842 return $this->pModifiers($node->flags)
Chris@0 843 . 'class' . $afterClassToken
Chris@0 844 . (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '')
Chris@0 845 . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '')
Chris@0 846 . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}';
Chris@0 847 }
Chris@0 848
Chris@0 849 protected function pObjectProperty($node) {
Chris@0 850 if ($node instanceof Expr) {
Chris@0 851 return '{' . $this->p($node) . '}';
Chris@0 852 } else {
Chris@0 853 return $node;
Chris@0 854 }
Chris@0 855 }
Chris@0 856
Chris@0 857 protected function pModifiers($modifiers) {
Chris@0 858 return ($modifiers & Stmt\Class_::MODIFIER_PUBLIC ? 'public ' : '')
Chris@0 859 . ($modifiers & Stmt\Class_::MODIFIER_PROTECTED ? 'protected ' : '')
Chris@0 860 . ($modifiers & Stmt\Class_::MODIFIER_PRIVATE ? 'private ' : '')
Chris@0 861 . ($modifiers & Stmt\Class_::MODIFIER_STATIC ? 'static ' : '')
Chris@0 862 . ($modifiers & Stmt\Class_::MODIFIER_ABSTRACT ? 'abstract ' : '')
Chris@0 863 . ($modifiers & Stmt\Class_::MODIFIER_FINAL ? 'final ' : '');
Chris@0 864 }
Chris@0 865
Chris@0 866 protected function pEncapsList(array $encapsList, $quote) {
Chris@0 867 $return = '';
Chris@0 868 foreach ($encapsList as $element) {
Chris@0 869 if ($element instanceof Scalar\EncapsedStringPart) {
Chris@0 870 $return .= $this->escapeString($element->value, $quote);
Chris@0 871 } else {
Chris@0 872 $return .= '{' . $this->p($element) . '}';
Chris@0 873 }
Chris@0 874 }
Chris@0 875
Chris@0 876 return $return;
Chris@0 877 }
Chris@0 878
Chris@0 879 protected function escapeString($string, $quote) {
Chris@0 880 if (null === $quote) {
Chris@0 881 // For doc strings, don't escape newlines
Chris@0 882 $escaped = addcslashes($string, "\t\f\v$\\");
Chris@0 883 } else {
Chris@0 884 $escaped = addcslashes($string, "\n\r\t\f\v$" . $quote . "\\");
Chris@0 885 }
Chris@0 886
Chris@0 887 // Escape other control characters
Chris@0 888 return preg_replace_callback('/([\0-\10\16-\37])(?=([0-7]?))/', function ($matches) {
Chris@0 889 $oct = decoct(ord($matches[1]));
Chris@0 890 if ($matches[2] !== '') {
Chris@0 891 // If there is a trailing digit, use the full three character form
Chris@0 892 return '\\' . str_pad($oct, 3, '0', STR_PAD_LEFT);
Chris@0 893 }
Chris@0 894 return '\\' . $oct;
Chris@0 895 }, $escaped);
Chris@0 896 }
Chris@0 897
Chris@0 898 protected function containsEndLabel($string, $label, $atStart = true, $atEnd = true) {
Chris@0 899 $start = $atStart ? '(?:^|[\r\n])' : '[\r\n]';
Chris@0 900 $end = $atEnd ? '(?:$|[;\r\n])' : '[;\r\n]';
Chris@0 901 return false !== strpos($string, $label)
Chris@0 902 && preg_match('/' . $start . $label . $end . '/', $string);
Chris@0 903 }
Chris@0 904
Chris@0 905 protected function encapsedContainsEndLabel(array $parts, $label) {
Chris@0 906 foreach ($parts as $i => $part) {
Chris@0 907 $atStart = $i === 0;
Chris@0 908 $atEnd = $i === count($parts) - 1;
Chris@0 909 if ($part instanceof Scalar\EncapsedStringPart
Chris@0 910 && $this->containsEndLabel($part->value, $label, $atStart, $atEnd)
Chris@0 911 ) {
Chris@0 912 return true;
Chris@0 913 }
Chris@0 914 }
Chris@0 915 return false;
Chris@0 916 }
Chris@0 917
Chris@0 918 protected function pDereferenceLhs(Node $node) {
Chris@0 919 if ($node instanceof Expr\Variable
Chris@0 920 || $node instanceof Name
Chris@0 921 || $node instanceof Expr\ArrayDimFetch
Chris@0 922 || $node instanceof Expr\PropertyFetch
Chris@0 923 || $node instanceof Expr\StaticPropertyFetch
Chris@0 924 || $node instanceof Expr\FuncCall
Chris@0 925 || $node instanceof Expr\MethodCall
Chris@0 926 || $node instanceof Expr\StaticCall
Chris@0 927 || $node instanceof Expr\Array_
Chris@0 928 || $node instanceof Scalar\String_
Chris@0 929 || $node instanceof Expr\ConstFetch
Chris@0 930 || $node instanceof Expr\ClassConstFetch
Chris@0 931 ) {
Chris@0 932 return $this->p($node);
Chris@0 933 } else {
Chris@0 934 return '(' . $this->p($node) . ')';
Chris@0 935 }
Chris@0 936 }
Chris@0 937
Chris@0 938 protected function pCallLhs(Node $node) {
Chris@0 939 if ($node instanceof Name
Chris@0 940 || $node instanceof Expr\Variable
Chris@0 941 || $node instanceof Expr\ArrayDimFetch
Chris@0 942 || $node instanceof Expr\FuncCall
Chris@0 943 || $node instanceof Expr\MethodCall
Chris@0 944 || $node instanceof Expr\StaticCall
Chris@0 945 || $node instanceof Expr\Array_
Chris@0 946 ) {
Chris@0 947 return $this->p($node);
Chris@0 948 } else {
Chris@0 949 return '(' . $this->p($node) . ')';
Chris@0 950 }
Chris@0 951 }
Chris@0 952
Chris@0 953 private function hasNodeWithComments(array $nodes) {
Chris@0 954 foreach ($nodes as $node) {
Chris@0 955 if ($node && $node->getAttribute('comments')) {
Chris@0 956 return true;
Chris@0 957 }
Chris@0 958 }
Chris@0 959 return false;
Chris@0 960 }
Chris@0 961
Chris@0 962 private function pMaybeMultiline(array $nodes, $trailingComma = false) {
Chris@0 963 if (!$this->hasNodeWithComments($nodes)) {
Chris@0 964 return $this->pCommaSeparated($nodes);
Chris@0 965 } else {
Chris@0 966 return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . "\n";
Chris@0 967 }
Chris@0 968 }
Chris@0 969 }