mirror of
https://github.com/danog/phpdoc-parser.git
synced 2024-11-30 04:29:20 +01:00
ConstFetchNode - supports all constants wildcard
This commit is contained in:
parent
cfd8285ccc
commit
fde6cca6d9
@ -53,8 +53,18 @@ class ConstExprParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_COLON)) {
|
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_COLON)) {
|
||||||
$classConstantName = $tokens->currentTokenValue();
|
$classConstantName = '';
|
||||||
|
if ($tokens->currentTokenType() === Lexer::TOKEN_IDENTIFIER) {
|
||||||
|
$classConstantName .= $tokens->currentTokenValue();
|
||||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||||
|
if ($tokens->tryConsumeTokenValue('*')) {
|
||||||
|
$classConstantName .= '*';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$tokens->consumeTokenValue('*');
|
||||||
|
$classConstantName .= '*';
|
||||||
|
}
|
||||||
|
|
||||||
return new Ast\ConstExpr\ConstFetchNode($identifier, $classConstantName);
|
return new Ast\ConstExpr\ConstFetchNode($identifier, $classConstantName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,27 +19,43 @@ class ParserException extends \Exception
|
|||||||
/** @var int */
|
/** @var int */
|
||||||
private $expectedTokenType;
|
private $expectedTokenType;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $expectedTokenValue;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $currentTokenValue,
|
string $currentTokenValue,
|
||||||
int $currentTokenType,
|
int $currentTokenType,
|
||||||
int $currentOffset,
|
int $currentOffset,
|
||||||
int $expectedTokenType
|
?int $expectedTokenType,
|
||||||
|
?string $expectedTokenValue = null
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
$this->currentTokenValue = $currentTokenValue;
|
$this->currentTokenValue = $currentTokenValue;
|
||||||
$this->currentTokenType = $currentTokenType;
|
$this->currentTokenType = $currentTokenType;
|
||||||
$this->currentOffset = $currentOffset;
|
$this->currentOffset = $currentOffset;
|
||||||
$this->expectedTokenType = $expectedTokenType;
|
$this->expectedTokenType = $expectedTokenType;
|
||||||
|
$this->expectedTokenValue = $expectedTokenValue;
|
||||||
|
|
||||||
$json = json_encode($currentTokenValue, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
$json = json_encode($currentTokenValue, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||||
assert($json !== false);
|
assert($json !== false);
|
||||||
|
|
||||||
|
if ($expectedTokenType !== null) {
|
||||||
parent::__construct(sprintf(
|
parent::__construct(sprintf(
|
||||||
'Unexpected token %s, expected %s at offset %d',
|
'Unexpected token %s, expected %s at offset %d',
|
||||||
$json,
|
$json,
|
||||||
Lexer::TOKEN_LABELS[$expectedTokenType],
|
Lexer::TOKEN_LABELS[$expectedTokenType],
|
||||||
$currentOffset
|
$currentOffset
|
||||||
));
|
));
|
||||||
|
} elseif ($expectedTokenValue !== null) {
|
||||||
|
parent::__construct(sprintf(
|
||||||
|
'Unexpected token value %s, expected value %s at offset %d',
|
||||||
|
$json,
|
||||||
|
$expectedTokenValue,
|
||||||
|
$currentOffset
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
throw new \LogicException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -66,4 +82,9 @@ class ParserException extends \Exception
|
|||||||
return $this->expectedTokenType;
|
return $this->expectedTokenType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getExpectedTokenValue(): string
|
||||||
|
{
|
||||||
|
return $this->expectedTokenValue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,25 @@ class TokenIterator
|
|||||||
return ($this->tokens[$this->index - 1][Lexer::TYPE_OFFSET] ?? -1) === Lexer::TOKEN_HORIZONTAL_WS;
|
return ($this->tokens[$this->index - 1][Lexer::TYPE_OFFSET] ?? -1) === Lexer::TOKEN_HORIZONTAL_WS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $tokenValue
|
||||||
|
* @throws \PHPStan\PhpDocParser\Parser\ParserException
|
||||||
|
*/
|
||||||
|
public function consumeTokenValue(string $tokenValue): void
|
||||||
|
{
|
||||||
|
if ($this->tokens[$this->index][Lexer::VALUE_OFFSET] !== $tokenValue) {
|
||||||
|
$this->throwError(null, $tokenValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->index++;
|
||||||
|
|
||||||
|
if (($this->tokens[$this->index][Lexer::TYPE_OFFSET] ?? -1) !== Lexer::TOKEN_HORIZONTAL_WS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $tokenType
|
* @param int $tokenType
|
||||||
@ -77,7 +96,7 @@ class TokenIterator
|
|||||||
public function consumeTokenType(int $tokenType): void
|
public function consumeTokenType(int $tokenType): void
|
||||||
{
|
{
|
||||||
if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] !== $tokenType) {
|
if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] !== $tokenType) {
|
||||||
$this->throwError($tokenType);
|
$this->throwError($tokenType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->index++;
|
$this->index++;
|
||||||
@ -175,16 +194,18 @@ class TokenIterator
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $expectedTokenType
|
* @param int|null $expectedTokenType
|
||||||
|
* @param string|null $expectedTokenValue
|
||||||
* @throws \PHPStan\PhpDocParser\Parser\ParserException
|
* @throws \PHPStan\PhpDocParser\Parser\ParserException
|
||||||
*/
|
*/
|
||||||
private function throwError(int $expectedTokenType): void
|
private function throwError(?int $expectedTokenType, ?string $expectedTokenValue): void
|
||||||
{
|
{
|
||||||
throw new \PHPStan\PhpDocParser\Parser\ParserException(
|
throw new \PHPStan\PhpDocParser\Parser\ParserException(
|
||||||
$this->currentTokenValue(),
|
$this->currentTokenValue(),
|
||||||
$this->currentTokenType(),
|
$this->currentTokenType(),
|
||||||
$this->currentTokenOffset(),
|
$this->currentTokenOffset(),
|
||||||
$expectedTokenType
|
$expectedTokenType,
|
||||||
|
$expectedTokenValue
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,12 +108,7 @@ class TypeParser
|
|||||||
if ($constExpr instanceof Ast\ConstExpr\ConstExprArrayNode) {
|
if ($constExpr instanceof Ast\ConstExpr\ConstExprArrayNode) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
}
|
}
|
||||||
if ($constExpr instanceof Ast\ConstExpr\ConstFetchNode) {
|
|
||||||
if ($tokens->currentTokenValue() === '*') {
|
|
||||||
$tokens->consumeTokenType($tokens->currentTokenType());
|
|
||||||
$constExpr = new Ast\ConstExpr\ConstFetchNode($constExpr->className, $constExpr->name . '*');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Ast\Type\ConstTypeNode($constExpr);
|
return new Ast\Type\ConstTypeNode($constExpr);
|
||||||
} catch (\LogicException $e) {
|
} catch (\LogicException $e) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
|
@ -858,6 +858,20 @@ class TypeParserTest extends \PHPUnit\Framework\TestCase
|
|||||||
'Foo::FOO_*',
|
'Foo::FOO_*',
|
||||||
new ConstTypeNode(new ConstFetchNode('Foo', 'FOO_*')),
|
new ConstTypeNode(new ConstFetchNode('Foo', 'FOO_*')),
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'Foo::*',
|
||||||
|
new ConstTypeNode(new ConstFetchNode('Foo', '*')),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Foo::**',
|
||||||
|
new \PHPStan\PhpDocParser\Parser\ParserException(
|
||||||
|
'**',
|
||||||
|
Lexer::TOKEN_END,
|
||||||
|
5,
|
||||||
|
null,
|
||||||
|
'*'
|
||||||
|
),
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'( "foo" | Foo::FOO_* )',
|
'( "foo" | Foo::FOO_* )',
|
||||||
new UnionTypeNode([
|
new UnionTypeNode([
|
||||||
|
Loading…
Reference in New Issue
Block a user