<?php
/*
* This file is part of Psy Shell.
*
* (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Psy\CodeCleaner;
use PhpParser\Node;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\Goto_;
use PhpParser\Node\Stmt\Label;
use Psy\Exception\FatalErrorException;
/**
* CodeCleanerPass for label context.
*
* This class partially emulates the PHP label specification.
* PsySH can not declare labels by sequentially executing lines with eval,
* but since it is not a syntax error, no error is raised.
* This class warns before invalid goto causes a fatal error.
* Since this is a simple checker, it does not block real fatal error
* with complex syntax. (ex. it does not parse inside function.)
*
* @see http://php.net/goto
*/
class LabelContextPass extends CodeCleanerPass
{
/** @var int */
private $functionDepth;
/** @var array */
private $labelDeclarations;
/** @var array */
private $labelGotos;
/**
* @param array $nodes
*
* @return Node[]|null Array of nodes
*/
public function beforeTraverse(array $nodes)
{
$this->functionDepth = 0;
$this->labelDeclarations = [];
$this->labelGotos = [];
}
/**
* @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
if ($node instanceof FunctionLike) {
$this->functionDepth++;
return;
}
// node is inside function context
if ($this->functionDepth !== 0) {
return;
}
if ($node instanceof Goto_) {
$this->labelGotos[\strtolower($node->name)] = $node->getStartLine();
} elseif ($node instanceof Label) {
$this->labelDeclarations[\strtolower($node->name)] = $node->getStartLine();
}
}
/**
* @param \PhpParser\Node $node
*
* @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
if ($node instanceof FunctionLike) {
$this->functionDepth--;
}
}
/**
* @return Node[]|null Array of nodes
*/
public function afterTraverse(array $nodes)
{
foreach ($this->labelGotos as $name => $line) {
if (!isset($this->labelDeclarations[$name])) {
$msg = "'goto' to undefined label '{$name}'";
throw new FatalErrorException($msg, 0, \E_ERROR, null, $line);
}
}
}
}
How To Payment
Making a payment on our website is quick and secure. Start by logging in or creating an account. Select your preferred payment method, input the required details, and review the information. Once you confirm everything is correct, click on the "Submit Payment" button. You’ll receive instant confirmation and can track your payment status through your account dashboard. It’s an easy and secure process.