晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。   林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。   见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝)   既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。   南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。 .
Prv8 Shell
Server : Apache
System : Linux srv.rainic.com 4.18.0-553.47.1.el8_10.x86_64 #1 SMP Wed Apr 2 05:45:37 EDT 2025 x86_64
User : rainic ( 1014)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /opt/cpanel/ea-wappspector/vendor/phpstan/phpdoc-parser/src/Parser/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //opt/cpanel/ea-wappspector/vendor/phpstan/phpdoc-parser/src/Parser/ConstExprParser.php
<?php declare(strict_types = 1);

namespace PHPStan\PhpDocParser\Parser;

use PHPStan\PhpDocParser\Ast;
use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\PhpDocParser\ParserConfig;
use function str_replace;
use function strtolower;

class ConstExprParser
{

	private ParserConfig $config;

	private bool $parseDoctrineStrings;

	public function __construct(
		ParserConfig $config
	)
	{
		$this->config = $config;
		$this->parseDoctrineStrings = false;
	}

	/**
	 * @internal
	 */
	public function toDoctrine(): self
	{
		$self = new self($this->config);
		$self->parseDoctrineStrings = true;
		return $self;
	}

	public function parse(TokenIterator $tokens): Ast\ConstExpr\ConstExprNode
	{
		$startLine = $tokens->currentTokenLine();
		$startIndex = $tokens->currentTokenIndex();
		if ($tokens->isCurrentTokenType(Lexer::TOKEN_FLOAT)) {
			$value = $tokens->currentTokenValue();
			$tokens->next();

			return $this->enrichWithAttributes(
				$tokens,
				new Ast\ConstExpr\ConstExprFloatNode(str_replace('_', '', $value)),
				$startLine,
				$startIndex,
			);
		}

		if ($tokens->isCurrentTokenType(Lexer::TOKEN_INTEGER)) {
			$value = $tokens->currentTokenValue();
			$tokens->next();

			return $this->enrichWithAttributes(
				$tokens,
				new Ast\ConstExpr\ConstExprIntegerNode(str_replace('_', '', $value)),
				$startLine,
				$startIndex,
			);
		}

		if ($this->parseDoctrineStrings && $tokens->isCurrentTokenType(Lexer::TOKEN_DOCTRINE_ANNOTATION_STRING)) {
			$value = $tokens->currentTokenValue();
			$tokens->next();

			return $this->enrichWithAttributes(
				$tokens,
				new Ast\ConstExpr\DoctrineConstExprStringNode(Ast\ConstExpr\DoctrineConstExprStringNode::unescape($value)),
				$startLine,
				$startIndex,
			);
		}

		if ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING, Lexer::TOKEN_DOUBLE_QUOTED_STRING)) {
			if ($this->parseDoctrineStrings) {
				if ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING)) {
					throw new ParserException(
						$tokens->currentTokenValue(),
						$tokens->currentTokenType(),
						$tokens->currentTokenOffset(),
						Lexer::TOKEN_DOUBLE_QUOTED_STRING,
						null,
						$tokens->currentTokenLine(),
					);
				}

				$value = $tokens->currentTokenValue();
				$tokens->next();

				return $this->enrichWithAttributes(
					$tokens,
					$this->parseDoctrineString($value, $tokens),
					$startLine,
					$startIndex,
				);
			}

			$value = StringUnescaper::unescapeString($tokens->currentTokenValue());
			$type = $tokens->currentTokenType();
			$tokens->next();

			return $this->enrichWithAttributes(
				$tokens,
				new Ast\ConstExpr\ConstExprStringNode(
					$value,
					$type === Lexer::TOKEN_SINGLE_QUOTED_STRING
						? Ast\ConstExpr\ConstExprStringNode::SINGLE_QUOTED
						: Ast\ConstExpr\ConstExprStringNode::DOUBLE_QUOTED,
				),
				$startLine,
				$startIndex,
			);

		} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) {
			$identifier = $tokens->currentTokenValue();
			$tokens->next();

			switch (strtolower($identifier)) {
				case 'true':
					return $this->enrichWithAttributes(
						$tokens,
						new Ast\ConstExpr\ConstExprTrueNode(),
						$startLine,
						$startIndex,
					);
				case 'false':
					return $this->enrichWithAttributes(
						$tokens,
						new Ast\ConstExpr\ConstExprFalseNode(),
						$startLine,
						$startIndex,
					);
				case 'null':
					return $this->enrichWithAttributes(
						$tokens,
						new Ast\ConstExpr\ConstExprNullNode(),
						$startLine,
						$startIndex,
					);
				case 'array':
					$tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES);
					return $this->parseArray($tokens, Lexer::TOKEN_CLOSE_PARENTHESES, $startIndex);
			}

			if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_COLON)) {
				$classConstantName = '';
				$lastType = null;
				while (true) {
					if ($lastType !== Lexer::TOKEN_IDENTIFIER && $tokens->currentTokenType() === Lexer::TOKEN_IDENTIFIER) {
						$classConstantName .= $tokens->currentTokenValue();
						$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
						$lastType = Lexer::TOKEN_IDENTIFIER;

						continue;
					}

					if ($lastType !== Lexer::TOKEN_WILDCARD && $tokens->tryConsumeTokenType(Lexer::TOKEN_WILDCARD)) {
						$classConstantName .= '*';
						$lastType = Lexer::TOKEN_WILDCARD;

						if ($tokens->getSkippedHorizontalWhiteSpaceIfAny() !== '') {
							break;
						}

						continue;
					}

					if ($lastType === null) {
						// trigger parse error if nothing valid was consumed
						$tokens->consumeTokenType(Lexer::TOKEN_WILDCARD);
					}

					break;
				}

				return $this->enrichWithAttributes(
					$tokens,
					new Ast\ConstExpr\ConstFetchNode($identifier, $classConstantName),
					$startLine,
					$startIndex,
				);

			}

			return $this->enrichWithAttributes(
				$tokens,
				new Ast\ConstExpr\ConstFetchNode('', $identifier),
				$startLine,
				$startIndex,
			);

		} elseif ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
			return $this->parseArray($tokens, Lexer::TOKEN_CLOSE_SQUARE_BRACKET, $startIndex);
		}

		throw new ParserException(
			$tokens->currentTokenValue(),
			$tokens->currentTokenType(),
			$tokens->currentTokenOffset(),
			Lexer::TOKEN_IDENTIFIER,
			null,
			$tokens->currentTokenLine(),
		);
	}


	private function parseArray(TokenIterator $tokens, int $endToken, int $startIndex): Ast\ConstExpr\ConstExprArrayNode
	{
		$items = [];

		$startLine = $tokens->currentTokenLine();

		if (!$tokens->tryConsumeTokenType($endToken)) {
			do {
				$items[] = $this->parseArrayItem($tokens);
			} while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA) && !$tokens->isCurrentTokenType($endToken));
			$tokens->consumeTokenType($endToken);
		}

		return $this->enrichWithAttributes(
			$tokens,
			new Ast\ConstExpr\ConstExprArrayNode($items),
			$startLine,
			$startIndex,
		);
	}


	/**
	 * This method is supposed to be called with TokenIterator after reading TOKEN_DOUBLE_QUOTED_STRING and shifting
	 * to the next token.
	 */
	public function parseDoctrineString(string $text, TokenIterator $tokens): Ast\ConstExpr\DoctrineConstExprStringNode
	{
		// Because of how Lexer works, a valid Doctrine string
		// can consist of a sequence of TOKEN_DOUBLE_QUOTED_STRING and TOKEN_DOCTRINE_ANNOTATION_STRING
		while ($tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_QUOTED_STRING, Lexer::TOKEN_DOCTRINE_ANNOTATION_STRING)) {
			$text .= $tokens->currentTokenValue();
			$tokens->next();
		}

		return new Ast\ConstExpr\DoctrineConstExprStringNode(Ast\ConstExpr\DoctrineConstExprStringNode::unescape($text));
	}


	private function parseArrayItem(TokenIterator $tokens): Ast\ConstExpr\ConstExprArrayItemNode
	{
		$startLine = $tokens->currentTokenLine();
		$startIndex = $tokens->currentTokenIndex();

		$expr = $this->parse($tokens);

		if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_ARROW)) {
			$key = $expr;
			$value = $this->parse($tokens);

		} else {
			$key = null;
			$value = $expr;
		}

		return $this->enrichWithAttributes(
			$tokens,
			new Ast\ConstExpr\ConstExprArrayItemNode($key, $value),
			$startLine,
			$startIndex,
		);
	}

	/**
	 * @template T of Ast\ConstExpr\ConstExprNode
	 * @param T $node
	 * @return T
	 */
	private function enrichWithAttributes(TokenIterator $tokens, Ast\ConstExpr\ConstExprNode $node, int $startLine, int $startIndex): Ast\ConstExpr\ConstExprNode
	{
		if ($this->config->useLinesAttributes) {
			$node->setAttribute(Ast\Attribute::START_LINE, $startLine);
			$node->setAttribute(Ast\Attribute::END_LINE, $tokens->currentTokenLine());
		}

		if ($this->config->useIndexAttributes) {
			$node->setAttribute(Ast\Attribute::START_INDEX, $startIndex);
			$node->setAttribute(Ast\Attribute::END_INDEX, $tokens->endIndexOfLastRelevantToken());
		}

		return $node;
	}

}

haha - 2025