composer base packages updates
This commit is contained in:
36
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayItemNode.php
vendored
Normal file
36
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayItemNode.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\ConstExpr;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function sprintf;
|
||||
|
||||
class ConstExprArrayItemNode implements ConstExprNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var ConstExprNode|null */
|
||||
public $key;
|
||||
|
||||
/** @var ConstExprNode */
|
||||
public $value;
|
||||
|
||||
public function __construct(?ConstExprNode $key, ConstExprNode $value)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
if ($this->key !== null) {
|
||||
return sprintf('%s => %s', $this->key, $this->value);
|
||||
|
||||
}
|
||||
|
||||
return (string) $this->value;
|
||||
}
|
||||
|
||||
}
|
||||
30
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayNode.php
vendored
Normal file
30
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayNode.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\ConstExpr;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function implode;
|
||||
|
||||
class ConstExprArrayNode implements ConstExprNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var ConstExprArrayItemNode[] */
|
||||
public $items;
|
||||
|
||||
/**
|
||||
* @param ConstExprArrayItemNode[] $items
|
||||
*/
|
||||
public function __construct(array $items)
|
||||
{
|
||||
$this->items = $items;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return '[' . implode(', ', $this->items) . ']';
|
||||
}
|
||||
|
||||
}
|
||||
17
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFalseNode.php
vendored
Normal file
17
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFalseNode.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\ConstExpr;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class ConstExprFalseNode implements ConstExprNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'false';
|
||||
}
|
||||
|
||||
}
|
||||
26
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFloatNode.php
vendored
Normal file
26
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFloatNode.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\ConstExpr;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class ConstExprFloatNode implements ConstExprNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string */
|
||||
public $value;
|
||||
|
||||
public function __construct(string $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
}
|
||||
26
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprIntegerNode.php
vendored
Normal file
26
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprIntegerNode.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\ConstExpr;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class ConstExprIntegerNode implements ConstExprNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string */
|
||||
public $value;
|
||||
|
||||
public function __construct(string $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
}
|
||||
10
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprNode.php
vendored
Normal file
10
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprNode.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\ConstExpr;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
|
||||
interface ConstExprNode extends Node
|
||||
{
|
||||
|
||||
}
|
||||
17
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprNullNode.php
vendored
Normal file
17
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprNullNode.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\ConstExpr;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class ConstExprNullNode implements ConstExprNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'null';
|
||||
}
|
||||
|
||||
}
|
||||
26
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprStringNode.php
vendored
Normal file
26
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprStringNode.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\ConstExpr;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class ConstExprStringNode implements ConstExprNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string */
|
||||
public $value;
|
||||
|
||||
public function __construct(string $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
}
|
||||
17
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprTrueNode.php
vendored
Normal file
17
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprTrueNode.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\ConstExpr;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class ConstExprTrueNode implements ConstExprNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'true';
|
||||
}
|
||||
|
||||
}
|
||||
35
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstFetchNode.php
vendored
Normal file
35
vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstFetchNode.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\ConstExpr;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class ConstFetchNode implements ConstExprNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string class name for class constants or empty string for non-class constants */
|
||||
public $className;
|
||||
|
||||
/** @var string */
|
||||
public $name;
|
||||
|
||||
public function __construct(string $className, string $name)
|
||||
{
|
||||
$this->className = $className;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
if ($this->className === '') {
|
||||
return $this->name;
|
||||
|
||||
}
|
||||
|
||||
return "{$this->className}::{$this->name}";
|
||||
}
|
||||
|
||||
}
|
||||
22
vendor/phpstan/phpdoc-parser/src/Ast/Node.php
vendored
Normal file
22
vendor/phpstan/phpdoc-parser/src/Ast/Node.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast;
|
||||
|
||||
interface Node
|
||||
{
|
||||
|
||||
public function __toString(): string;
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setAttribute(string $key, $value): void;
|
||||
|
||||
public function hasAttribute(string $key): bool;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute(string $key);
|
||||
|
||||
}
|
||||
38
vendor/phpstan/phpdoc-parser/src/Ast/NodeAttributes.php
vendored
Normal file
38
vendor/phpstan/phpdoc-parser/src/Ast/NodeAttributes.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
trait NodeAttributes
|
||||
{
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
private $attributes = [];
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setAttribute(string $key, $value): void
|
||||
{
|
||||
$this->attributes[$key] = $value;
|
||||
}
|
||||
|
||||
public function hasAttribute(string $key): bool
|
||||
{
|
||||
return array_key_exists($key, $this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute(string $key)
|
||||
{
|
||||
if ($this->hasAttribute($key)) {
|
||||
return $this->attributes[$key];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
50
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagMethodValueNode.php
vendored
Normal file
50
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagMethodValueNode.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class AssertTagMethodValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string */
|
||||
public $parameter;
|
||||
|
||||
/** @var string */
|
||||
public $method;
|
||||
|
||||
/** @var bool */
|
||||
public $isNegated;
|
||||
|
||||
/** @var bool */
|
||||
public $isEquality;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, string $parameter, string $method, bool $isNegated, string $description, bool $isEquality = false)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->parameter = $parameter;
|
||||
$this->method = $method;
|
||||
$this->isNegated = $isNegated;
|
||||
$this->isEquality = $isEquality;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$isNegated = $this->isNegated ? '!' : '';
|
||||
$isEquality = $this->isEquality ? '=' : '';
|
||||
return trim("{$isNegated}{$isEquality}{$this->type} {$this->parameter}->{$this->method}() {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
50
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagPropertyValueNode.php
vendored
Normal file
50
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagPropertyValueNode.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class AssertTagPropertyValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string */
|
||||
public $parameter;
|
||||
|
||||
/** @var string */
|
||||
public $property;
|
||||
|
||||
/** @var bool */
|
||||
public $isNegated;
|
||||
|
||||
/** @var bool */
|
||||
public $isEquality;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, string $parameter, string $property, bool $isNegated, string $description, bool $isEquality = false)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->parameter = $parameter;
|
||||
$this->property = $property;
|
||||
$this->isNegated = $isNegated;
|
||||
$this->isEquality = $isEquality;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$isNegated = $this->isNegated ? '!' : '';
|
||||
$isEquality = $this->isEquality ? '=' : '';
|
||||
return trim("{$isNegated}{$isEquality}{$this->type} {$this->parameter}->{$this->property} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
46
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagValueNode.php
vendored
Normal file
46
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagValueNode.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class AssertTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string */
|
||||
public $parameter;
|
||||
|
||||
/** @var bool */
|
||||
public $isNegated;
|
||||
|
||||
/** @var bool */
|
||||
public $isEquality;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, string $parameter, bool $isNegated, string $description, bool $isEquality = false)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->parameter = $parameter;
|
||||
$this->isNegated = $isNegated;
|
||||
$this->isEquality = $isEquality;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$isNegated = $this->isNegated ? '!' : '';
|
||||
$isEquality = $this->isEquality ? '=' : '';
|
||||
return trim("{$isNegated}{$isEquality}{$this->type} {$this->parameter} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
27
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/DeprecatedTagValueNode.php
vendored
Normal file
27
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/DeprecatedTagValueNode.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function trim;
|
||||
|
||||
class DeprecatedTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(string $description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim($this->description);
|
||||
}
|
||||
|
||||
}
|
||||
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ExtendsTagValueNode.php
vendored
Normal file
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ExtendsTagValueNode.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
|
||||
use function trim;
|
||||
|
||||
class ExtendsTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var GenericTypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(GenericTypeNode $type, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->type} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
26
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/GenericTagValueNode.php
vendored
Normal file
26
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/GenericTagValueNode.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class GenericTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $value;
|
||||
|
||||
public function __construct(string $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
}
|
||||
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ImplementsTagValueNode.php
vendored
Normal file
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ImplementsTagValueNode.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
|
||||
use function trim;
|
||||
|
||||
class ImplementsTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var GenericTypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(GenericTypeNode $type, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->type} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
52
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/InvalidTagValueNode.php
vendored
Normal file
52
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/InvalidTagValueNode.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Parser\ParserException;
|
||||
use function sprintf;
|
||||
use function trigger_error;
|
||||
use const E_USER_WARNING;
|
||||
|
||||
/**
|
||||
* @property ParserException $exception
|
||||
*/
|
||||
class InvalidTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $value;
|
||||
|
||||
/** @var mixed[] */
|
||||
private $exceptionArgs;
|
||||
|
||||
public function __construct(string $value, ParserException $exception)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->exceptionArgs = [
|
||||
$exception->getCurrentTokenValue(),
|
||||
$exception->getCurrentTokenType(),
|
||||
$exception->getCurrentOffset(),
|
||||
$exception->getExpectedTokenType(),
|
||||
$exception->getExpectedTokenValue(),
|
||||
];
|
||||
}
|
||||
|
||||
public function __get(string $name)
|
||||
{
|
||||
if ($name !== 'exception') {
|
||||
trigger_error(sprintf('Undefined property: %s::$%s', self::class, $name), E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ParserException(...$this->exceptionArgs);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
}
|
||||
54
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueNode.php
vendored
Normal file
54
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueNode.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function count;
|
||||
use function implode;
|
||||
|
||||
class MethodTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var bool */
|
||||
public $isStatic;
|
||||
|
||||
/** @var TypeNode|null */
|
||||
public $returnType;
|
||||
|
||||
/** @var string */
|
||||
public $methodName;
|
||||
|
||||
/** @var TemplateTagValueNode[] */
|
||||
public $templateTypes;
|
||||
|
||||
/** @var MethodTagValueParameterNode[] */
|
||||
public $parameters;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(bool $isStatic, ?TypeNode $returnType, string $methodName, array $parameters, string $description, array $templateTypes = [])
|
||||
{
|
||||
$this->isStatic = $isStatic;
|
||||
$this->returnType = $returnType;
|
||||
$this->methodName = $methodName;
|
||||
$this->parameters = $parameters;
|
||||
$this->description = $description;
|
||||
$this->templateTypes = $templateTypes;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$static = $this->isStatic ? 'static ' : '';
|
||||
$returnType = $this->returnType !== null ? "{$this->returnType} " : '';
|
||||
$parameters = implode(', ', $this->parameters);
|
||||
$description = $this->description !== '' ? " {$this->description}" : '';
|
||||
$templateTypes = count($this->templateTypes) > 0 ? '<' . implode(', ', $this->templateTypes) . '>' : '';
|
||||
return "{$static}{$returnType}{$this->methodName}{$templateTypes}({$parameters}){$description}";
|
||||
}
|
||||
|
||||
}
|
||||
49
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueParameterNode.php
vendored
Normal file
49
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueParameterNode.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprNode;
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
|
||||
class MethodTagValueParameterNode implements Node
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode|null */
|
||||
public $type;
|
||||
|
||||
/** @var bool */
|
||||
public $isReference;
|
||||
|
||||
/** @var bool */
|
||||
public $isVariadic;
|
||||
|
||||
/** @var string */
|
||||
public $parameterName;
|
||||
|
||||
/** @var ConstExprNode|null */
|
||||
public $defaultValue;
|
||||
|
||||
public function __construct(?TypeNode $type, bool $isReference, bool $isVariadic, string $parameterName, ?ConstExprNode $defaultValue)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->isReference = $isReference;
|
||||
$this->isVariadic = $isVariadic;
|
||||
$this->parameterName = $parameterName;
|
||||
$this->defaultValue = $defaultValue;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$type = $this->type !== null ? "{$this->type} " : '';
|
||||
$isReference = $this->isReference ? '&' : '';
|
||||
$isVariadic = $this->isVariadic ? '...' : '';
|
||||
$default = $this->defaultValue !== null ? " = {$this->defaultValue}" : '';
|
||||
return "{$type}{$isReference}{$isVariadic}{$this->parameterName}{$default}";
|
||||
}
|
||||
|
||||
}
|
||||
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MixinTagValueNode.php
vendored
Normal file
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MixinTagValueNode.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class MixinTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->type} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
35
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamOutTagValueNode.php
vendored
Normal file
35
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamOutTagValueNode.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class ParamOutTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string */
|
||||
public $parameterName;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, string $parameterName, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->parameterName = $parameterName;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->type} {$this->parameterName} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
46
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamTagValueNode.php
vendored
Normal file
46
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamTagValueNode.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class ParamTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var bool */
|
||||
public $isReference;
|
||||
|
||||
/** @var bool */
|
||||
public $isVariadic;
|
||||
|
||||
/** @var string */
|
||||
public $parameterName;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, bool $isVariadic, string $parameterName, string $description, bool $isReference = false)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->isReference = $isReference;
|
||||
$this->isVariadic = $isVariadic;
|
||||
$this->parameterName = $parameterName;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$reference = $this->isReference ? '&' : '';
|
||||
$variadic = $this->isVariadic ? '...' : '';
|
||||
return trim("{$this->type} {$reference}{$variadic}{$this->parameterName} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
10
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocChildNode.php
vendored
Normal file
10
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocChildNode.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
|
||||
interface PhpDocChildNode extends Node
|
||||
{
|
||||
|
||||
}
|
||||
371
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocNode.php
vendored
Normal file
371
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocNode.php
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function array_column;
|
||||
use function array_filter;
|
||||
use function array_map;
|
||||
use function implode;
|
||||
|
||||
class PhpDocNode implements Node
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var PhpDocChildNode[] */
|
||||
public $children;
|
||||
|
||||
/**
|
||||
* @param PhpDocChildNode[] $children
|
||||
*/
|
||||
public function __construct(array $children)
|
||||
{
|
||||
$this->children = $children;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return PhpDocTagNode[]
|
||||
*/
|
||||
public function getTags(): array
|
||||
{
|
||||
return array_filter($this->children, static function (PhpDocChildNode $child): bool {
|
||||
return $child instanceof PhpDocTagNode;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return PhpDocTagNode[]
|
||||
*/
|
||||
public function getTagsByName(string $tagName): array
|
||||
{
|
||||
return array_filter($this->getTags(), static function (PhpDocTagNode $tag) use ($tagName): bool {
|
||||
return $tag->name === $tagName;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return VarTagValueNode[]
|
||||
*/
|
||||
public function getVarTagValues(string $tagName = '@var'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof VarTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ParamTagValueNode[]
|
||||
*/
|
||||
public function getParamTagValues(string $tagName = '@param'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof ParamTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TypelessParamTagValueNode[]
|
||||
*/
|
||||
public function getTypelessParamTagValues(string $tagName = '@param'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof TypelessParamTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TemplateTagValueNode[]
|
||||
*/
|
||||
public function getTemplateTagValues(string $tagName = '@template'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof TemplateTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ExtendsTagValueNode[]
|
||||
*/
|
||||
public function getExtendsTagValues(string $tagName = '@extends'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof ExtendsTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ImplementsTagValueNode[]
|
||||
*/
|
||||
public function getImplementsTagValues(string $tagName = '@implements'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof ImplementsTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return UsesTagValueNode[]
|
||||
*/
|
||||
public function getUsesTagValues(string $tagName = '@use'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof UsesTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ReturnTagValueNode[]
|
||||
*/
|
||||
public function getReturnTagValues(string $tagName = '@return'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof ReturnTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ThrowsTagValueNode[]
|
||||
*/
|
||||
public function getThrowsTagValues(string $tagName = '@throws'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof ThrowsTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return MixinTagValueNode[]
|
||||
*/
|
||||
public function getMixinTagValues(string $tagName = '@mixin'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof MixinTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return DeprecatedTagValueNode[]
|
||||
*/
|
||||
public function getDeprecatedTagValues(): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName('@deprecated'), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof DeprecatedTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return PropertyTagValueNode[]
|
||||
*/
|
||||
public function getPropertyTagValues(string $tagName = '@property'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof PropertyTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return PropertyTagValueNode[]
|
||||
*/
|
||||
public function getPropertyReadTagValues(string $tagName = '@property-read'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof PropertyTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return PropertyTagValueNode[]
|
||||
*/
|
||||
public function getPropertyWriteTagValues(string $tagName = '@property-write'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof PropertyTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return MethodTagValueNode[]
|
||||
*/
|
||||
public function getMethodTagValues(string $tagName = '@method'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof MethodTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TypeAliasTagValueNode[]
|
||||
*/
|
||||
public function getTypeAliasTagValues(string $tagName = '@phpstan-type'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof TypeAliasTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return TypeAliasImportTagValueNode[]
|
||||
*/
|
||||
public function getTypeAliasImportTagValues(string $tagName = '@phpstan-import-type'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof TypeAliasImportTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return AssertTagValueNode[]
|
||||
*/
|
||||
public function getAssertTagValues(string $tagName = '@phpstan-assert'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof AssertTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return AssertTagPropertyValueNode[]
|
||||
*/
|
||||
public function getAssertPropertyTagValues(string $tagName = '@phpstan-assert'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof AssertTagPropertyValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return AssertTagMethodValueNode[]
|
||||
*/
|
||||
public function getAssertMethodTagValues(string $tagName = '@phpstan-assert'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof AssertTagMethodValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return SelfOutTagValueNode[]
|
||||
*/
|
||||
public function getSelfOutTypeTagValues(string $tagName = '@phpstan-this-out'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof SelfOutTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ParamOutTagValueNode[]
|
||||
*/
|
||||
public function getParamOutTypeTagValues(string $tagName = '@param-out'): array
|
||||
{
|
||||
return array_filter(
|
||||
array_column($this->getTagsByName($tagName), 'value'),
|
||||
static function (PhpDocTagValueNode $value): bool {
|
||||
return $value instanceof ParamOutTagValueNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$children = array_map(
|
||||
static function (PhpDocChildNode $child): string {
|
||||
$s = (string) $child;
|
||||
return $s === '' ? '' : ' ' . $s;
|
||||
},
|
||||
$this->children
|
||||
);
|
||||
return "/**\n *" . implode("\n *", $children) . "\n */";
|
||||
}
|
||||
|
||||
}
|
||||
31
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagNode.php
vendored
Normal file
31
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagNode.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function trim;
|
||||
|
||||
class PhpDocTagNode implements PhpDocChildNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string */
|
||||
public $name;
|
||||
|
||||
/** @var PhpDocTagValueNode */
|
||||
public $value;
|
||||
|
||||
public function __construct(string $name, PhpDocTagValueNode $value)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->name} {$this->value}");
|
||||
}
|
||||
|
||||
}
|
||||
10
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.php
vendored
Normal file
10
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
|
||||
interface PhpDocTagValueNode extends Node
|
||||
{
|
||||
|
||||
}
|
||||
26
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTextNode.php
vendored
Normal file
26
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTextNode.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class PhpDocTextNode implements PhpDocChildNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string */
|
||||
public $text;
|
||||
|
||||
public function __construct(string $text)
|
||||
{
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
}
|
||||
36
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PropertyTagValueNode.php
vendored
Normal file
36
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PropertyTagValueNode.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class PropertyTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string */
|
||||
public $propertyName;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, string $propertyName, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->propertyName = $propertyName;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->type} {$this->propertyName} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ReturnTagValueNode.php
vendored
Normal file
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ReturnTagValueNode.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class ReturnTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->type} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/SelfOutTagValueNode.php
vendored
Normal file
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/SelfOutTagValueNode.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class SelfOutTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim($this->type . ' ' . $this->description);
|
||||
}
|
||||
|
||||
}
|
||||
42
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TemplateTagValueNode.php
vendored
Normal file
42
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TemplateTagValueNode.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class TemplateTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string */
|
||||
public $name;
|
||||
|
||||
/** @var TypeNode|null */
|
||||
public $bound;
|
||||
|
||||
/** @var TypeNode|null */
|
||||
public $default;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(string $name, ?TypeNode $bound, string $description, ?TypeNode $default = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->bound = $bound;
|
||||
$this->default = $default;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$bound = $this->bound !== null ? " of {$this->bound}" : '';
|
||||
$default = $this->default !== null ? " = {$this->default}" : '';
|
||||
return trim("{$this->name}{$bound}{$default} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ThrowsTagValueNode.php
vendored
Normal file
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ThrowsTagValueNode.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class ThrowsTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->type} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
38
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypeAliasImportTagValueNode.php
vendored
Normal file
38
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypeAliasImportTagValueNode.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use function trim;
|
||||
|
||||
class TypeAliasImportTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string */
|
||||
public $importedAlias;
|
||||
|
||||
/** @var IdentifierTypeNode */
|
||||
public $importedFrom;
|
||||
|
||||
/** @var string|null */
|
||||
public $importedAs;
|
||||
|
||||
public function __construct(string $importedAlias, IdentifierTypeNode $importedFrom, ?string $importedAs)
|
||||
{
|
||||
$this->importedAlias = $importedAlias;
|
||||
$this->importedFrom = $importedFrom;
|
||||
$this->importedAs = $importedAs;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim(
|
||||
"{$this->importedAlias} from {$this->importedFrom}"
|
||||
. ($this->importedAs !== null ? " as {$this->importedAs}" : '')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypeAliasTagValueNode.php
vendored
Normal file
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypeAliasTagValueNode.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class TypeAliasTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string */
|
||||
public $alias;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
public function __construct(string $alias, TypeNode $type)
|
||||
{
|
||||
$this->alias = $alias;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->alias} {$this->type}");
|
||||
}
|
||||
|
||||
}
|
||||
41
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypelessParamTagValueNode.php
vendored
Normal file
41
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypelessParamTagValueNode.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function trim;
|
||||
|
||||
class TypelessParamTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var bool */
|
||||
public $isReference;
|
||||
|
||||
/** @var bool */
|
||||
public $isVariadic;
|
||||
|
||||
/** @var string */
|
||||
public $parameterName;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(bool $isVariadic, string $parameterName, string $description, bool $isReference = false)
|
||||
{
|
||||
$this->isReference = $isReference;
|
||||
$this->isVariadic = $isVariadic;
|
||||
$this->parameterName = $parameterName;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$reference = $this->isReference ? '&' : '';
|
||||
$variadic = $this->isVariadic ? '...' : '';
|
||||
return trim("{$reference}{$variadic}{$this->parameterName} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/UsesTagValueNode.php
vendored
Normal file
32
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/UsesTagValueNode.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
|
||||
use function trim;
|
||||
|
||||
class UsesTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var GenericTypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(GenericTypeNode $type, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("{$this->type} {$this->description}");
|
||||
}
|
||||
|
||||
}
|
||||
36
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/VarTagValueNode.php
vendored
Normal file
36
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/VarTagValueNode.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
|
||||
class VarTagValueNode implements PhpDocTagValueNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $variableName;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
|
||||
public function __construct(TypeNode $type, string $variableName, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->variableName = $variableName;
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return trim("$this->type " . trim("{$this->variableName} {$this->description}"));
|
||||
}
|
||||
|
||||
}
|
||||
49
vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeItemNode.php
vendored
Normal file
49
vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeItemNode.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
|
||||
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function sprintf;
|
||||
|
||||
class ArrayShapeItemNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var ConstExprIntegerNode|ConstExprStringNode|IdentifierTypeNode|null */
|
||||
public $keyName;
|
||||
|
||||
/** @var bool */
|
||||
public $optional;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $valueType;
|
||||
|
||||
/**
|
||||
* @param ConstExprIntegerNode|ConstExprStringNode|IdentifierTypeNode|null $keyName
|
||||
*/
|
||||
public function __construct($keyName, bool $optional, TypeNode $valueType)
|
||||
{
|
||||
$this->keyName = $keyName;
|
||||
$this->optional = $optional;
|
||||
$this->valueType = $valueType;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
if ($this->keyName !== null) {
|
||||
return sprintf(
|
||||
'%s%s: %s',
|
||||
(string) $this->keyName,
|
||||
$this->optional ? '?' : '',
|
||||
(string) $this->valueType
|
||||
);
|
||||
}
|
||||
|
||||
return (string) $this->valueType;
|
||||
}
|
||||
|
||||
}
|
||||
47
vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeNode.php
vendored
Normal file
47
vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeNode.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function implode;
|
||||
|
||||
class ArrayShapeNode implements TypeNode
|
||||
{
|
||||
|
||||
public const KIND_ARRAY = 'array';
|
||||
public const KIND_LIST = 'list';
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var ArrayShapeItemNode[] */
|
||||
public $items;
|
||||
|
||||
/** @var bool */
|
||||
public $sealed;
|
||||
|
||||
/** @var self::KIND_* */
|
||||
public $kind;
|
||||
|
||||
/**
|
||||
* @param self::KIND_* $kind
|
||||
*/
|
||||
public function __construct(array $items, bool $sealed = true, string $kind = self::KIND_ARRAY)
|
||||
{
|
||||
$this->items = $items;
|
||||
$this->sealed = $sealed;
|
||||
$this->kind = $kind;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$items = $this->items;
|
||||
|
||||
if (! $this->sealed) {
|
||||
$items[] = '...';
|
||||
}
|
||||
|
||||
return $this->kind . '{' . implode(', ', $items) . '}';
|
||||
}
|
||||
|
||||
}
|
||||
26
vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayTypeNode.php
vendored
Normal file
26
vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayTypeNode.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class ArrayTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
public function __construct(TypeNode $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->type . '[]';
|
||||
}
|
||||
|
||||
}
|
||||
36
vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeNode.php
vendored
Normal file
36
vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeNode.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function implode;
|
||||
|
||||
class CallableTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var IdentifierTypeNode */
|
||||
public $identifier;
|
||||
|
||||
/** @var CallableTypeParameterNode[] */
|
||||
public $parameters;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $returnType;
|
||||
|
||||
public function __construct(IdentifierTypeNode $identifier, array $parameters, TypeNode $returnType)
|
||||
{
|
||||
$this->identifier = $identifier;
|
||||
$this->parameters = $parameters;
|
||||
$this->returnType = $returnType;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$parameters = implode(', ', $this->parameters);
|
||||
return "{$this->identifier}({$parameters}): {$this->returnType}";
|
||||
}
|
||||
|
||||
}
|
||||
48
vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeParameterNode.php
vendored
Normal file
48
vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeParameterNode.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function trim;
|
||||
|
||||
class CallableTypeParameterNode implements Node
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var bool */
|
||||
public $isReference;
|
||||
|
||||
/** @var bool */
|
||||
public $isVariadic;
|
||||
|
||||
/** @var string (may be empty) */
|
||||
public $parameterName;
|
||||
|
||||
/** @var bool */
|
||||
public $isOptional;
|
||||
|
||||
public function __construct(TypeNode $type, bool $isReference, bool $isVariadic, string $parameterName, bool $isOptional)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->isReference = $isReference;
|
||||
$this->isVariadic = $isVariadic;
|
||||
$this->parameterName = $parameterName;
|
||||
$this->isOptional = $isOptional;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$type = "{$this->type} ";
|
||||
$isReference = $this->isReference ? '&' : '';
|
||||
$isVariadic = $this->isVariadic ? '...' : '';
|
||||
$default = $this->isOptional ? ' = default' : '';
|
||||
return trim("{$type}{$isReference}{$isVariadic}{$this->parameterName}") . $default;
|
||||
}
|
||||
|
||||
}
|
||||
49
vendor/phpstan/phpdoc-parser/src/Ast/Type/ConditionalTypeForParameterNode.php
vendored
Normal file
49
vendor/phpstan/phpdoc-parser/src/Ast/Type/ConditionalTypeForParameterNode.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function sprintf;
|
||||
|
||||
class ConditionalTypeForParameterNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string */
|
||||
public $parameterName;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $targetType;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $if;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $else;
|
||||
|
||||
/** @var bool */
|
||||
public $negated;
|
||||
|
||||
public function __construct(string $parameterName, TypeNode $targetType, TypeNode $if, TypeNode $else, bool $negated)
|
||||
{
|
||||
$this->parameterName = $parameterName;
|
||||
$this->targetType = $targetType;
|
||||
$this->if = $if;
|
||||
$this->else = $else;
|
||||
$this->negated = $negated;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf(
|
||||
'(%s %s %s ? %s : %s)',
|
||||
$this->parameterName,
|
||||
$this->negated ? 'is not' : 'is',
|
||||
$this->targetType,
|
||||
$this->if,
|
||||
$this->else
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
49
vendor/phpstan/phpdoc-parser/src/Ast/Type/ConditionalTypeNode.php
vendored
Normal file
49
vendor/phpstan/phpdoc-parser/src/Ast/Type/ConditionalTypeNode.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function sprintf;
|
||||
|
||||
class ConditionalTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $subjectType;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $targetType;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $if;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $else;
|
||||
|
||||
/** @var bool */
|
||||
public $negated;
|
||||
|
||||
public function __construct(TypeNode $subjectType, TypeNode $targetType, TypeNode $if, TypeNode $else, bool $negated)
|
||||
{
|
||||
$this->subjectType = $subjectType;
|
||||
$this->targetType = $targetType;
|
||||
$this->if = $if;
|
||||
$this->else = $else;
|
||||
$this->negated = $negated;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf(
|
||||
'(%s %s %s ? %s : %s)',
|
||||
$this->subjectType,
|
||||
$this->negated ? 'is not' : 'is',
|
||||
$this->targetType,
|
||||
$this->if,
|
||||
$this->else
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
26
vendor/phpstan/phpdoc-parser/src/Ast/Type/ConstTypeNode.php
vendored
Normal file
26
vendor/phpstan/phpdoc-parser/src/Ast/Type/ConstTypeNode.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprNode;
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class ConstTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var ConstExprNode */
|
||||
public $constExpr;
|
||||
|
||||
public function __construct(ConstExprNode $constExpr)
|
||||
{
|
||||
$this->constExpr = $constExpr;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->constExpr->__toString();
|
||||
}
|
||||
|
||||
}
|
||||
54
vendor/phpstan/phpdoc-parser/src/Ast/Type/GenericTypeNode.php
vendored
Normal file
54
vendor/phpstan/phpdoc-parser/src/Ast/Type/GenericTypeNode.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function implode;
|
||||
use function sprintf;
|
||||
|
||||
class GenericTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
public const VARIANCE_INVARIANT = 'invariant';
|
||||
public const VARIANCE_COVARIANT = 'covariant';
|
||||
public const VARIANCE_CONTRAVARIANT = 'contravariant';
|
||||
public const VARIANCE_BIVARIANT = 'bivariant';
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var IdentifierTypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var TypeNode[] */
|
||||
public $genericTypes;
|
||||
|
||||
/** @var (self::VARIANCE_*)[] */
|
||||
public $variances;
|
||||
|
||||
public function __construct(IdentifierTypeNode $type, array $genericTypes, array $variances = [])
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->genericTypes = $genericTypes;
|
||||
$this->variances = $variances;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$genericTypes = [];
|
||||
|
||||
foreach ($this->genericTypes as $index => $type) {
|
||||
$variance = $this->variances[$index] ?? self::VARIANCE_INVARIANT;
|
||||
if ($variance === self::VARIANCE_INVARIANT) {
|
||||
$genericTypes[] = (string) $type;
|
||||
} elseif ($variance === self::VARIANCE_BIVARIANT) {
|
||||
$genericTypes[] = '*';
|
||||
} else {
|
||||
$genericTypes[] = sprintf('%s %s', $variance, $type);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->type . '<' . implode(', ', $genericTypes) . '>';
|
||||
}
|
||||
|
||||
}
|
||||
26
vendor/phpstan/phpdoc-parser/src/Ast/Type/IdentifierTypeNode.php
vendored
Normal file
26
vendor/phpstan/phpdoc-parser/src/Ast/Type/IdentifierTypeNode.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class IdentifierTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var string */
|
||||
public $name;
|
||||
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
}
|
||||
27
vendor/phpstan/phpdoc-parser/src/Ast/Type/IntersectionTypeNode.php
vendored
Normal file
27
vendor/phpstan/phpdoc-parser/src/Ast/Type/IntersectionTypeNode.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function implode;
|
||||
|
||||
class IntersectionTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode[] */
|
||||
public $types;
|
||||
|
||||
public function __construct(array $types)
|
||||
{
|
||||
$this->types = $types;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return '(' . implode(' & ', $this->types) . ')';
|
||||
}
|
||||
|
||||
}
|
||||
26
vendor/phpstan/phpdoc-parser/src/Ast/Type/NullableTypeNode.php
vendored
Normal file
26
vendor/phpstan/phpdoc-parser/src/Ast/Type/NullableTypeNode.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class NullableTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
public function __construct(TypeNode $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return '?' . $this->type;
|
||||
}
|
||||
|
||||
}
|
||||
29
vendor/phpstan/phpdoc-parser/src/Ast/Type/OffsetAccessTypeNode.php
vendored
Normal file
29
vendor/phpstan/phpdoc-parser/src/Ast/Type/OffsetAccessTypeNode.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class OffsetAccessTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
|
||||
/** @var TypeNode */
|
||||
public $offset;
|
||||
|
||||
public function __construct(TypeNode $type, TypeNode $offset)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->offset = $offset;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->type . '[' . $this->offset . ']';
|
||||
}
|
||||
|
||||
}
|
||||
17
vendor/phpstan/phpdoc-parser/src/Ast/Type/ThisTypeNode.php
vendored
Normal file
17
vendor/phpstan/phpdoc-parser/src/Ast/Type/ThisTypeNode.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
|
||||
class ThisTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return '$this';
|
||||
}
|
||||
|
||||
}
|
||||
10
vendor/phpstan/phpdoc-parser/src/Ast/Type/TypeNode.php
vendored
Normal file
10
vendor/phpstan/phpdoc-parser/src/Ast/Type/TypeNode.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
|
||||
interface TypeNode extends Node
|
||||
{
|
||||
|
||||
}
|
||||
27
vendor/phpstan/phpdoc-parser/src/Ast/Type/UnionTypeNode.php
vendored
Normal file
27
vendor/phpstan/phpdoc-parser/src/Ast/Type/UnionTypeNode.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast\Type;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use function implode;
|
||||
|
||||
class UnionTypeNode implements TypeNode
|
||||
{
|
||||
|
||||
use NodeAttributes;
|
||||
|
||||
/** @var TypeNode[] */
|
||||
public $types;
|
||||
|
||||
public function __construct(array $types)
|
||||
{
|
||||
$this->types = $types;
|
||||
}
|
||||
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return '(' . implode(' | ', $this->types) . ')';
|
||||
}
|
||||
|
||||
}
|
||||
170
vendor/phpstan/phpdoc-parser/src/Lexer/Lexer.php
vendored
Normal file
170
vendor/phpstan/phpdoc-parser/src/Lexer/Lexer.php
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Lexer;
|
||||
|
||||
use function implode;
|
||||
use function preg_match_all;
|
||||
use const PREG_SET_ORDER;
|
||||
|
||||
/**
|
||||
* Implementation based on Nette Tokenizer (New BSD License; https://github.com/nette/tokenizer)
|
||||
*/
|
||||
class Lexer
|
||||
{
|
||||
|
||||
public const TOKEN_REFERENCE = 0;
|
||||
public const TOKEN_UNION = 1;
|
||||
public const TOKEN_INTERSECTION = 2;
|
||||
public const TOKEN_NULLABLE = 3;
|
||||
public const TOKEN_OPEN_PARENTHESES = 4;
|
||||
public const TOKEN_CLOSE_PARENTHESES = 5;
|
||||
public const TOKEN_OPEN_ANGLE_BRACKET = 6;
|
||||
public const TOKEN_CLOSE_ANGLE_BRACKET = 7;
|
||||
public const TOKEN_OPEN_SQUARE_BRACKET = 8;
|
||||
public const TOKEN_CLOSE_SQUARE_BRACKET = 9;
|
||||
public const TOKEN_COMMA = 10;
|
||||
public const TOKEN_VARIADIC = 11;
|
||||
public const TOKEN_DOUBLE_COLON = 12;
|
||||
public const TOKEN_DOUBLE_ARROW = 13;
|
||||
public const TOKEN_EQUAL = 14;
|
||||
public const TOKEN_OPEN_PHPDOC = 15;
|
||||
public const TOKEN_CLOSE_PHPDOC = 16;
|
||||
public const TOKEN_PHPDOC_TAG = 17;
|
||||
public const TOKEN_FLOAT = 18;
|
||||
public const TOKEN_INTEGER = 19;
|
||||
public const TOKEN_SINGLE_QUOTED_STRING = 20;
|
||||
public const TOKEN_DOUBLE_QUOTED_STRING = 21;
|
||||
public const TOKEN_IDENTIFIER = 22;
|
||||
public const TOKEN_THIS_VARIABLE = 23;
|
||||
public const TOKEN_VARIABLE = 24;
|
||||
public const TOKEN_HORIZONTAL_WS = 25;
|
||||
public const TOKEN_PHPDOC_EOL = 26;
|
||||
public const TOKEN_OTHER = 27;
|
||||
public const TOKEN_END = 28;
|
||||
public const TOKEN_COLON = 29;
|
||||
public const TOKEN_WILDCARD = 30;
|
||||
public const TOKEN_OPEN_CURLY_BRACKET = 31;
|
||||
public const TOKEN_CLOSE_CURLY_BRACKET = 32;
|
||||
public const TOKEN_NEGATED = 33;
|
||||
public const TOKEN_ARROW = 34;
|
||||
|
||||
public const TOKEN_LABELS = [
|
||||
self::TOKEN_REFERENCE => '\'&\'',
|
||||
self::TOKEN_UNION => '\'|\'',
|
||||
self::TOKEN_INTERSECTION => '\'&\'',
|
||||
self::TOKEN_NULLABLE => '\'?\'',
|
||||
self::TOKEN_NEGATED => '\'!\'',
|
||||
self::TOKEN_OPEN_PARENTHESES => '\'(\'',
|
||||
self::TOKEN_CLOSE_PARENTHESES => '\')\'',
|
||||
self::TOKEN_OPEN_ANGLE_BRACKET => '\'<\'',
|
||||
self::TOKEN_CLOSE_ANGLE_BRACKET => '\'>\'',
|
||||
self::TOKEN_OPEN_SQUARE_BRACKET => '\'[\'',
|
||||
self::TOKEN_CLOSE_SQUARE_BRACKET => '\']\'',
|
||||
self::TOKEN_OPEN_CURLY_BRACKET => '\'{\'',
|
||||
self::TOKEN_CLOSE_CURLY_BRACKET => '\'}\'',
|
||||
self::TOKEN_COMMA => '\',\'',
|
||||
self::TOKEN_COLON => '\':\'',
|
||||
self::TOKEN_VARIADIC => '\'...\'',
|
||||
self::TOKEN_DOUBLE_COLON => '\'::\'',
|
||||
self::TOKEN_DOUBLE_ARROW => '\'=>\'',
|
||||
self::TOKEN_ARROW => '\'->\'',
|
||||
self::TOKEN_EQUAL => '\'=\'',
|
||||
self::TOKEN_OPEN_PHPDOC => '\'/**\'',
|
||||
self::TOKEN_CLOSE_PHPDOC => '\'*/\'',
|
||||
self::TOKEN_PHPDOC_TAG => 'TOKEN_PHPDOC_TAG',
|
||||
self::TOKEN_PHPDOC_EOL => 'TOKEN_PHPDOC_EOL',
|
||||
self::TOKEN_FLOAT => 'TOKEN_FLOAT',
|
||||
self::TOKEN_INTEGER => 'TOKEN_INTEGER',
|
||||
self::TOKEN_SINGLE_QUOTED_STRING => 'TOKEN_SINGLE_QUOTED_STRING',
|
||||
self::TOKEN_DOUBLE_QUOTED_STRING => 'TOKEN_DOUBLE_QUOTED_STRING',
|
||||
self::TOKEN_IDENTIFIER => 'type',
|
||||
self::TOKEN_THIS_VARIABLE => '\'$this\'',
|
||||
self::TOKEN_VARIABLE => 'variable',
|
||||
self::TOKEN_HORIZONTAL_WS => 'TOKEN_HORIZONTAL_WS',
|
||||
self::TOKEN_OTHER => 'TOKEN_OTHER',
|
||||
self::TOKEN_END => 'TOKEN_END',
|
||||
self::TOKEN_WILDCARD => '*',
|
||||
];
|
||||
|
||||
public const VALUE_OFFSET = 0;
|
||||
public const TYPE_OFFSET = 1;
|
||||
|
||||
/** @var string|null */
|
||||
private $regexp;
|
||||
|
||||
public function tokenize(string $s): array
|
||||
{
|
||||
if ($this->regexp === null) {
|
||||
$this->regexp = $this->generateRegexp();
|
||||
}
|
||||
|
||||
preg_match_all($this->regexp, $s, $matches, PREG_SET_ORDER);
|
||||
|
||||
$tokens = [];
|
||||
foreach ($matches as $match) {
|
||||
$tokens[] = [$match[0], (int) $match['MARK']];
|
||||
}
|
||||
|
||||
$tokens[] = ['', self::TOKEN_END];
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
|
||||
private function generateRegexp(): string
|
||||
{
|
||||
$patterns = [
|
||||
self::TOKEN_HORIZONTAL_WS => '[\\x09\\x20]++',
|
||||
|
||||
self::TOKEN_IDENTIFIER => '(?:[\\\\]?+[a-z_\\x80-\\xFF][0-9a-z_\\x80-\\xFF-]*+)++',
|
||||
self::TOKEN_THIS_VARIABLE => '\\$this(?![0-9a-z_\\x80-\\xFF])',
|
||||
self::TOKEN_VARIABLE => '\\$[a-z_\\x80-\\xFF][0-9a-z_\\x80-\\xFF]*+',
|
||||
|
||||
// '&' followed by TOKEN_VARIADIC, TOKEN_VARIABLE, TOKEN_EQUAL, TOKEN_EQUAL or TOKEN_CLOSE_PARENTHESES
|
||||
self::TOKEN_REFERENCE => '&(?=\\s*+(?:[.,=)]|(?:\\$(?!this(?![0-9a-z_\\x80-\\xFF])))))',
|
||||
self::TOKEN_UNION => '\\|',
|
||||
self::TOKEN_INTERSECTION => '&',
|
||||
self::TOKEN_NULLABLE => '\\?',
|
||||
self::TOKEN_NEGATED => '!',
|
||||
|
||||
self::TOKEN_OPEN_PARENTHESES => '\\(',
|
||||
self::TOKEN_CLOSE_PARENTHESES => '\\)',
|
||||
self::TOKEN_OPEN_ANGLE_BRACKET => '<',
|
||||
self::TOKEN_CLOSE_ANGLE_BRACKET => '>',
|
||||
self::TOKEN_OPEN_SQUARE_BRACKET => '\\[',
|
||||
self::TOKEN_CLOSE_SQUARE_BRACKET => '\\]',
|
||||
self::TOKEN_OPEN_CURLY_BRACKET => '\\{',
|
||||
self::TOKEN_CLOSE_CURLY_BRACKET => '\\}',
|
||||
|
||||
self::TOKEN_COMMA => ',',
|
||||
self::TOKEN_VARIADIC => '\\.\\.\\.',
|
||||
self::TOKEN_DOUBLE_COLON => '::',
|
||||
self::TOKEN_DOUBLE_ARROW => '=>',
|
||||
self::TOKEN_ARROW => '->',
|
||||
self::TOKEN_EQUAL => '=',
|
||||
self::TOKEN_COLON => ':',
|
||||
|
||||
self::TOKEN_OPEN_PHPDOC => '/\\*\\*(?=\\s)\\x20?+',
|
||||
self::TOKEN_CLOSE_PHPDOC => '\\*/',
|
||||
self::TOKEN_PHPDOC_TAG => '@(?:[a-z][a-z0-9-\\\\]+:)?[a-z][a-z0-9-\\\\]*+',
|
||||
self::TOKEN_PHPDOC_EOL => '\\r?+\\n[\\x09\\x20]*+(?:\\*(?!/)\\x20?+)?',
|
||||
|
||||
self::TOKEN_FLOAT => '(?:-?[0-9]++\\.[0-9]*+(?:e-?[0-9]++)?)|(?:-?[0-9]*+\\.[0-9]++(?:e-?[0-9]++)?)|(?:-?[0-9]++e-?[0-9]++)',
|
||||
self::TOKEN_INTEGER => '-?(?:(?:0b[0-1]++)|(?:0o[0-7]++)|(?:0x[0-9a-f]++)|(?:[0-9]++))',
|
||||
self::TOKEN_SINGLE_QUOTED_STRING => '\'(?:\\\\[^\\r\\n]|[^\'\\r\\n\\\\])*+\'',
|
||||
self::TOKEN_DOUBLE_QUOTED_STRING => '"(?:\\\\[^\\r\\n]|[^"\\r\\n\\\\])*+"',
|
||||
|
||||
self::TOKEN_WILDCARD => '\\*',
|
||||
|
||||
// anything but TOKEN_CLOSE_PHPDOC or TOKEN_HORIZONTAL_WS or TOKEN_EOL
|
||||
self::TOKEN_OTHER => '(?:(?!\\*/)[^\\s])++',
|
||||
];
|
||||
|
||||
foreach ($patterns as $type => &$pattern) {
|
||||
$pattern = '(?:' . $pattern . ')(*MARK:' . $type . ')';
|
||||
}
|
||||
|
||||
return '~' . implode('|', $patterns) . '~Asi';
|
||||
}
|
||||
|
||||
}
|
||||
230
vendor/phpstan/phpdoc-parser/src/Parser/ConstExprParser.php
vendored
Normal file
230
vendor/phpstan/phpdoc-parser/src/Parser/ConstExprParser.php
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Parser;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use function chr;
|
||||
use function hexdec;
|
||||
use function octdec;
|
||||
use function preg_replace_callback;
|
||||
use function str_replace;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
|
||||
class ConstExprParser
|
||||
{
|
||||
|
||||
private const REPLACEMENTS = [
|
||||
'\\' => '\\',
|
||||
'n' => "\n",
|
||||
'r' => "\r",
|
||||
't' => "\t",
|
||||
'f' => "\f",
|
||||
'v' => "\v",
|
||||
'e' => "\x1B",
|
||||
];
|
||||
|
||||
/** @var bool */
|
||||
private $unescapeStrings;
|
||||
|
||||
public function __construct(bool $unescapeStrings = false)
|
||||
{
|
||||
$this->unescapeStrings = $unescapeStrings;
|
||||
}
|
||||
|
||||
public function parse(TokenIterator $tokens, bool $trimStrings = false): Ast\ConstExpr\ConstExprNode
|
||||
{
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_FLOAT)) {
|
||||
$value = $tokens->currentTokenValue();
|
||||
$tokens->next();
|
||||
return new Ast\ConstExpr\ConstExprFloatNode($value);
|
||||
}
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_INTEGER)) {
|
||||
$value = $tokens->currentTokenValue();
|
||||
$tokens->next();
|
||||
return new Ast\ConstExpr\ConstExprIntegerNode($value);
|
||||
}
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING, Lexer::TOKEN_DOUBLE_QUOTED_STRING)) {
|
||||
$value = $tokens->currentTokenValue();
|
||||
if ($trimStrings) {
|
||||
if ($this->unescapeStrings) {
|
||||
$value = self::unescapeString($value);
|
||||
} else {
|
||||
$value = substr($value, 1, -1);
|
||||
}
|
||||
}
|
||||
$tokens->next();
|
||||
return new Ast\ConstExpr\ConstExprStringNode($value);
|
||||
|
||||
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) {
|
||||
$identifier = $tokens->currentTokenValue();
|
||||
$tokens->next();
|
||||
|
||||
switch (strtolower($identifier)) {
|
||||
case 'true':
|
||||
return new Ast\ConstExpr\ConstExprTrueNode();
|
||||
case 'false':
|
||||
return new Ast\ConstExpr\ConstExprFalseNode();
|
||||
case 'null':
|
||||
return new Ast\ConstExpr\ConstExprNullNode();
|
||||
case 'array':
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES);
|
||||
return $this->parseArray($tokens, Lexer::TOKEN_CLOSE_PARENTHESES);
|
||||
}
|
||||
|
||||
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 new Ast\ConstExpr\ConstFetchNode($identifier, $classConstantName);
|
||||
|
||||
}
|
||||
|
||||
return new Ast\ConstExpr\ConstFetchNode('', $identifier);
|
||||
|
||||
} elseif ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
|
||||
return $this->parseArray($tokens, Lexer::TOKEN_CLOSE_SQUARE_BRACKET);
|
||||
}
|
||||
|
||||
throw new ParserException(
|
||||
$tokens->currentTokenValue(),
|
||||
$tokens->currentTokenType(),
|
||||
$tokens->currentTokenOffset(),
|
||||
Lexer::TOKEN_IDENTIFIER
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private function parseArray(TokenIterator $tokens, int $endToken): Ast\ConstExpr\ConstExprArrayNode
|
||||
{
|
||||
$items = [];
|
||||
|
||||
if (!$tokens->tryConsumeTokenType($endToken)) {
|
||||
do {
|
||||
$items[] = $this->parseArrayItem($tokens);
|
||||
} while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA) && !$tokens->isCurrentTokenType($endToken));
|
||||
$tokens->consumeTokenType($endToken);
|
||||
}
|
||||
|
||||
return new Ast\ConstExpr\ConstExprArrayNode($items);
|
||||
}
|
||||
|
||||
|
||||
private function parseArrayItem(TokenIterator $tokens): Ast\ConstExpr\ConstExprArrayItemNode
|
||||
{
|
||||
$expr = $this->parse($tokens);
|
||||
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_ARROW)) {
|
||||
$key = $expr;
|
||||
$value = $this->parse($tokens);
|
||||
|
||||
} else {
|
||||
$key = null;
|
||||
$value = $expr;
|
||||
}
|
||||
|
||||
return new Ast\ConstExpr\ConstExprArrayItemNode($key, $value);
|
||||
}
|
||||
|
||||
private static function unescapeString(string $string): string
|
||||
{
|
||||
$quote = $string[0];
|
||||
|
||||
if ($quote === '\'') {
|
||||
return str_replace(
|
||||
['\\\\', '\\\''],
|
||||
['\\', '\''],
|
||||
substr($string, 1, -1)
|
||||
);
|
||||
}
|
||||
|
||||
return self::parseEscapeSequences(substr($string, 1, -1), '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation based on https://github.com/nikic/PHP-Parser/blob/b0edd4c41111042d43bb45c6c657b2e0db367d9e/lib/PhpParser/Node/Scalar/String_.php#L90-L130
|
||||
*/
|
||||
private static function parseEscapeSequences(string $str, string $quote): string
|
||||
{
|
||||
$str = str_replace('\\' . $quote, $quote, $str);
|
||||
|
||||
return preg_replace_callback(
|
||||
'~\\\\([\\\\nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}|u\{([0-9a-fA-F]+)\})~',
|
||||
static function ($matches) {
|
||||
$str = $matches[1];
|
||||
|
||||
if (isset(self::REPLACEMENTS[$str])) {
|
||||
return self::REPLACEMENTS[$str];
|
||||
}
|
||||
if ($str[0] === 'x' || $str[0] === 'X') {
|
||||
return chr(hexdec(substr($str, 1)));
|
||||
}
|
||||
if ($str[0] === 'u') {
|
||||
return self::codePointToUtf8(hexdec($matches[2]));
|
||||
}
|
||||
|
||||
return chr(octdec($str));
|
||||
},
|
||||
$str
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation based on https://github.com/nikic/PHP-Parser/blob/b0edd4c41111042d43bb45c6c657b2e0db367d9e/lib/PhpParser/Node/Scalar/String_.php#L132-L154
|
||||
*/
|
||||
private static function codePointToUtf8(int $num): string
|
||||
{
|
||||
if ($num <= 0x7F) {
|
||||
return chr($num);
|
||||
}
|
||||
if ($num <= 0x7FF) {
|
||||
return chr(($num >> 6) + 0xC0)
|
||||
. chr(($num & 0x3F) + 0x80);
|
||||
}
|
||||
if ($num <= 0xFFFF) {
|
||||
return chr(($num >> 12) + 0xE0)
|
||||
. chr((($num >> 6) & 0x3F) + 0x80)
|
||||
. chr(($num & 0x3F) + 0x80);
|
||||
}
|
||||
if ($num <= 0x1FFFFF) {
|
||||
return chr(($num >> 18) + 0xF0)
|
||||
. chr((($num >> 12) & 0x3F) + 0x80)
|
||||
. chr((($num >> 6) & 0x3F) + 0x80)
|
||||
. chr(($num & 0x3F) + 0x80);
|
||||
}
|
||||
|
||||
// Invalid UTF-8 codepoint escape sequence: Codepoint too large
|
||||
return "\xef\xbf\xbd";
|
||||
}
|
||||
|
||||
}
|
||||
93
vendor/phpstan/phpdoc-parser/src/Parser/ParserException.php
vendored
Normal file
93
vendor/phpstan/phpdoc-parser/src/Parser/ParserException.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Parser;
|
||||
|
||||
use Exception;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use function assert;
|
||||
use function json_encode;
|
||||
use function sprintf;
|
||||
use const JSON_UNESCAPED_SLASHES;
|
||||
use const JSON_UNESCAPED_UNICODE;
|
||||
|
||||
class ParserException extends Exception
|
||||
{
|
||||
|
||||
/** @var string */
|
||||
private $currentTokenValue;
|
||||
|
||||
/** @var int */
|
||||
private $currentTokenType;
|
||||
|
||||
/** @var int */
|
||||
private $currentOffset;
|
||||
|
||||
/** @var int */
|
||||
private $expectedTokenType;
|
||||
|
||||
/** @var string|null */
|
||||
private $expectedTokenValue;
|
||||
|
||||
public function __construct(
|
||||
string $currentTokenValue,
|
||||
int $currentTokenType,
|
||||
int $currentOffset,
|
||||
int $expectedTokenType,
|
||||
?string $expectedTokenValue = null
|
||||
)
|
||||
{
|
||||
$this->currentTokenValue = $currentTokenValue;
|
||||
$this->currentTokenType = $currentTokenType;
|
||||
$this->currentOffset = $currentOffset;
|
||||
$this->expectedTokenType = $expectedTokenType;
|
||||
$this->expectedTokenValue = $expectedTokenValue;
|
||||
|
||||
parent::__construct(sprintf(
|
||||
'Unexpected token %s, expected %s%s at offset %d',
|
||||
$this->formatValue($currentTokenValue),
|
||||
Lexer::TOKEN_LABELS[$expectedTokenType],
|
||||
$expectedTokenValue !== null ? sprintf(' (%s)', $this->formatValue($expectedTokenValue)) : '',
|
||||
$currentOffset
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
public function getCurrentTokenValue(): string
|
||||
{
|
||||
return $this->currentTokenValue;
|
||||
}
|
||||
|
||||
|
||||
public function getCurrentTokenType(): int
|
||||
{
|
||||
return $this->currentTokenType;
|
||||
}
|
||||
|
||||
|
||||
public function getCurrentOffset(): int
|
||||
{
|
||||
return $this->currentOffset;
|
||||
}
|
||||
|
||||
|
||||
public function getExpectedTokenType(): int
|
||||
{
|
||||
return $this->expectedTokenType;
|
||||
}
|
||||
|
||||
|
||||
public function getExpectedTokenValue(): ?string
|
||||
{
|
||||
return $this->expectedTokenValue;
|
||||
}
|
||||
|
||||
|
||||
private function formatValue(string $value): string
|
||||
{
|
||||
$json = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
assert($json !== false);
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
}
|
||||
598
vendor/phpstan/phpdoc-parser/src/Parser/PhpDocParser.php
vendored
Normal file
598
vendor/phpstan/phpdoc-parser/src/Parser/PhpDocParser.php
vendored
Normal file
@@ -0,0 +1,598 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Parser;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use PHPStan\ShouldNotHappenException;
|
||||
use function array_key_exists;
|
||||
use function array_values;
|
||||
use function count;
|
||||
use function trim;
|
||||
|
||||
class PhpDocParser
|
||||
{
|
||||
|
||||
private const DISALLOWED_DESCRIPTION_START_TOKENS = [
|
||||
Lexer::TOKEN_UNION,
|
||||
Lexer::TOKEN_INTERSECTION,
|
||||
];
|
||||
|
||||
/** @var TypeParser */
|
||||
private $typeParser;
|
||||
|
||||
/** @var ConstExprParser */
|
||||
private $constantExprParser;
|
||||
|
||||
/** @var bool */
|
||||
private $requireWhitespaceBeforeDescription;
|
||||
|
||||
public function __construct(TypeParser $typeParser, ConstExprParser $constantExprParser, bool $requireWhitespaceBeforeDescription = false)
|
||||
{
|
||||
$this->typeParser = $typeParser;
|
||||
$this->constantExprParser = $constantExprParser;
|
||||
$this->requireWhitespaceBeforeDescription = $requireWhitespaceBeforeDescription;
|
||||
}
|
||||
|
||||
|
||||
public function parse(TokenIterator $tokens): Ast\PhpDoc\PhpDocNode
|
||||
{
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_PHPDOC);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
$children = [];
|
||||
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
|
||||
$children[] = $this->parseChild($tokens);
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL) && !$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) {
|
||||
$children[] = $this->parseChild($tokens);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PHPDOC);
|
||||
} catch (ParserException $e) {
|
||||
$name = '';
|
||||
if (count($children) > 0) {
|
||||
$lastChild = $children[count($children) - 1];
|
||||
if ($lastChild instanceof Ast\PhpDoc\PhpDocTagNode) {
|
||||
$name = $lastChild->name;
|
||||
}
|
||||
}
|
||||
$tokens->forwardToTheEnd();
|
||||
return new Ast\PhpDoc\PhpDocNode([
|
||||
new Ast\PhpDoc\PhpDocTagNode($name, new Ast\PhpDoc\InvalidTagValueNode($e->getMessage(), $e)),
|
||||
]);
|
||||
}
|
||||
|
||||
return new Ast\PhpDoc\PhpDocNode(array_values($children));
|
||||
}
|
||||
|
||||
|
||||
private function parseChild(TokenIterator $tokens): Ast\PhpDoc\PhpDocChildNode
|
||||
{
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_TAG)) {
|
||||
return $this->parseTag($tokens);
|
||||
|
||||
}
|
||||
|
||||
return $this->parseText($tokens);
|
||||
}
|
||||
|
||||
|
||||
private function parseText(TokenIterator $tokens): Ast\PhpDoc\PhpDocTextNode
|
||||
{
|
||||
$text = '';
|
||||
|
||||
while (!$tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL)) {
|
||||
$text .= $tokens->getSkippedHorizontalWhiteSpaceIfAny() . $tokens->joinUntil(Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END);
|
||||
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$tokens->pushSavePoint();
|
||||
$tokens->next();
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_TAG, Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END)) {
|
||||
$tokens->rollback();
|
||||
break;
|
||||
}
|
||||
|
||||
$tokens->dropSavePoint();
|
||||
$text .= "\n";
|
||||
}
|
||||
|
||||
return new Ast\PhpDoc\PhpDocTextNode(trim($text, " \t"));
|
||||
}
|
||||
|
||||
|
||||
public function parseTag(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagNode
|
||||
{
|
||||
$tag = $tokens->currentTokenValue();
|
||||
$tokens->next();
|
||||
$value = $this->parseTagValue($tokens, $tag);
|
||||
|
||||
return new Ast\PhpDoc\PhpDocTagNode($tag, $value);
|
||||
}
|
||||
|
||||
|
||||
public function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\PhpDocTagValueNode
|
||||
{
|
||||
try {
|
||||
$tokens->pushSavePoint();
|
||||
|
||||
switch ($tag) {
|
||||
case '@param':
|
||||
case '@phpstan-param':
|
||||
case '@psalm-param':
|
||||
$tagValue = $this->parseParamTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@var':
|
||||
case '@phpstan-var':
|
||||
case '@psalm-var':
|
||||
$tagValue = $this->parseVarTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@return':
|
||||
case '@phpstan-return':
|
||||
case '@psalm-return':
|
||||
$tagValue = $this->parseReturnTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@throws':
|
||||
case '@phpstan-throws':
|
||||
$tagValue = $this->parseThrowsTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@mixin':
|
||||
$tagValue = $this->parseMixinTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@deprecated':
|
||||
$tagValue = $this->parseDeprecatedTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@property':
|
||||
case '@property-read':
|
||||
case '@property-write':
|
||||
case '@phpstan-property':
|
||||
case '@phpstan-property-read':
|
||||
case '@phpstan-property-write':
|
||||
case '@psalm-property':
|
||||
case '@psalm-property-read':
|
||||
case '@psalm-property-write':
|
||||
$tagValue = $this->parsePropertyTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@method':
|
||||
case '@phpstan-method':
|
||||
case '@psalm-method':
|
||||
$tagValue = $this->parseMethodTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@template':
|
||||
case '@phpstan-template':
|
||||
case '@psalm-template':
|
||||
case '@template-covariant':
|
||||
case '@phpstan-template-covariant':
|
||||
case '@psalm-template-covariant':
|
||||
case '@template-contravariant':
|
||||
case '@phpstan-template-contravariant':
|
||||
case '@psalm-template-contravariant':
|
||||
$tagValue = $this->parseTemplateTagValue($tokens, true);
|
||||
break;
|
||||
|
||||
case '@extends':
|
||||
case '@phpstan-extends':
|
||||
case '@template-extends':
|
||||
$tagValue = $this->parseExtendsTagValue('@extends', $tokens);
|
||||
break;
|
||||
|
||||
case '@implements':
|
||||
case '@phpstan-implements':
|
||||
case '@template-implements':
|
||||
$tagValue = $this->parseExtendsTagValue('@implements', $tokens);
|
||||
break;
|
||||
|
||||
case '@use':
|
||||
case '@phpstan-use':
|
||||
case '@template-use':
|
||||
$tagValue = $this->parseExtendsTagValue('@use', $tokens);
|
||||
break;
|
||||
|
||||
case '@phpstan-type':
|
||||
case '@psalm-type':
|
||||
$tagValue = $this->parseTypeAliasTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@phpstan-import-type':
|
||||
case '@psalm-import-type':
|
||||
$tagValue = $this->parseTypeAliasImportTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@phpstan-assert':
|
||||
case '@phpstan-assert-if-true':
|
||||
case '@phpstan-assert-if-false':
|
||||
case '@psalm-assert':
|
||||
case '@psalm-assert-if-true':
|
||||
case '@psalm-assert-if-false':
|
||||
$tagValue = $this->parseAssertTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@phpstan-this-out':
|
||||
case '@phpstan-self-out':
|
||||
case '@psalm-this-out':
|
||||
case '@psalm-self-out':
|
||||
$tagValue = $this->parseSelfOutTagValue($tokens);
|
||||
break;
|
||||
|
||||
case '@param-out':
|
||||
case '@phpstan-param-out':
|
||||
case '@psalm-param-out':
|
||||
$tagValue = $this->parseParamOutTagValue($tokens);
|
||||
break;
|
||||
|
||||
default:
|
||||
$tagValue = new Ast\PhpDoc\GenericTagValueNode($this->parseOptionalDescription($tokens));
|
||||
break;
|
||||
}
|
||||
|
||||
$tokens->dropSavePoint();
|
||||
|
||||
} catch (ParserException $e) {
|
||||
$tokens->rollback();
|
||||
$tagValue = new Ast\PhpDoc\InvalidTagValueNode($this->parseOptionalDescription($tokens), $e);
|
||||
}
|
||||
|
||||
return $tagValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Ast\PhpDoc\ParamTagValueNode|Ast\PhpDoc\TypelessParamTagValueNode
|
||||
*/
|
||||
private function parseParamTagValue(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagValueNode
|
||||
{
|
||||
if (
|
||||
$tokens->isCurrentTokenType(Lexer::TOKEN_REFERENCE)
|
||||
|| $tokens->isCurrentTokenType(Lexer::TOKEN_VARIADIC)
|
||||
|| $tokens->isCurrentTokenType(Lexer::TOKEN_VARIABLE)
|
||||
) {
|
||||
$type = null;
|
||||
} else {
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
}
|
||||
|
||||
$isReference = $tokens->tryConsumeTokenType(Lexer::TOKEN_REFERENCE);
|
||||
$isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC);
|
||||
$parameterName = $this->parseRequiredVariableName($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
|
||||
if ($type !== null) {
|
||||
return new Ast\PhpDoc\ParamTagValueNode($type, $isVariadic, $parameterName, $description, $isReference);
|
||||
}
|
||||
|
||||
return new Ast\PhpDoc\TypelessParamTagValueNode($isVariadic, $parameterName, $description, $isReference);
|
||||
}
|
||||
|
||||
|
||||
private function parseVarTagValue(TokenIterator $tokens): Ast\PhpDoc\VarTagValueNode
|
||||
{
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
$variableName = $this->parseOptionalVariableName($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens, $variableName === '');
|
||||
return new Ast\PhpDoc\VarTagValueNode($type, $variableName, $description);
|
||||
}
|
||||
|
||||
|
||||
private function parseReturnTagValue(TokenIterator $tokens): Ast\PhpDoc\ReturnTagValueNode
|
||||
{
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens, true);
|
||||
return new Ast\PhpDoc\ReturnTagValueNode($type, $description);
|
||||
}
|
||||
|
||||
|
||||
private function parseThrowsTagValue(TokenIterator $tokens): Ast\PhpDoc\ThrowsTagValueNode
|
||||
{
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens, true);
|
||||
return new Ast\PhpDoc\ThrowsTagValueNode($type, $description);
|
||||
}
|
||||
|
||||
private function parseMixinTagValue(TokenIterator $tokens): Ast\PhpDoc\MixinTagValueNode
|
||||
{
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens, true);
|
||||
return new Ast\PhpDoc\MixinTagValueNode($type, $description);
|
||||
}
|
||||
|
||||
private function parseDeprecatedTagValue(TokenIterator $tokens): Ast\PhpDoc\DeprecatedTagValueNode
|
||||
{
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
return new Ast\PhpDoc\DeprecatedTagValueNode($description);
|
||||
}
|
||||
|
||||
|
||||
private function parsePropertyTagValue(TokenIterator $tokens): Ast\PhpDoc\PropertyTagValueNode
|
||||
{
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
$parameterName = $this->parseRequiredVariableName($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
return new Ast\PhpDoc\PropertyTagValueNode($type, $parameterName, $description);
|
||||
}
|
||||
|
||||
|
||||
private function parseMethodTagValue(TokenIterator $tokens): Ast\PhpDoc\MethodTagValueNode
|
||||
{
|
||||
$isStatic = $tokens->tryConsumeTokenValue('static');
|
||||
$returnTypeOrMethodName = $this->typeParser->parse($tokens);
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) {
|
||||
$returnType = $returnTypeOrMethodName;
|
||||
$methodName = $tokens->currentTokenValue();
|
||||
$tokens->next();
|
||||
|
||||
} elseif ($returnTypeOrMethodName instanceof Ast\Type\IdentifierTypeNode) {
|
||||
$returnType = $isStatic ? new Ast\Type\IdentifierTypeNode('static') : null;
|
||||
$methodName = $returnTypeOrMethodName->name;
|
||||
$isStatic = false;
|
||||
|
||||
} else {
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); // will throw exception
|
||||
exit;
|
||||
}
|
||||
|
||||
$templateTypes = [];
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) {
|
||||
do {
|
||||
$templateTypes[] = $this->parseTemplateTagValue($tokens, false);
|
||||
} while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA));
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET);
|
||||
}
|
||||
|
||||
$parameters = [];
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES);
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) {
|
||||
$parameters[] = $this->parseMethodTagValueParameter($tokens);
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
|
||||
$parameters[] = $this->parseMethodTagValueParameter($tokens);
|
||||
}
|
||||
}
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES);
|
||||
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
return new Ast\PhpDoc\MethodTagValueNode($isStatic, $returnType, $methodName, $parameters, $description, $templateTypes);
|
||||
}
|
||||
|
||||
private function parseMethodTagValueParameter(TokenIterator $tokens): Ast\PhpDoc\MethodTagValueParameterNode
|
||||
{
|
||||
switch ($tokens->currentTokenType()) {
|
||||
case Lexer::TOKEN_IDENTIFIER:
|
||||
case Lexer::TOKEN_OPEN_PARENTHESES:
|
||||
case Lexer::TOKEN_NULLABLE:
|
||||
$parameterType = $this->typeParser->parse($tokens);
|
||||
break;
|
||||
|
||||
default:
|
||||
$parameterType = null;
|
||||
}
|
||||
|
||||
$isReference = $tokens->tryConsumeTokenType(Lexer::TOKEN_REFERENCE);
|
||||
$isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC);
|
||||
|
||||
$parameterName = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_VARIABLE);
|
||||
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL)) {
|
||||
$defaultValue = $this->constantExprParser->parse($tokens);
|
||||
|
||||
} else {
|
||||
$defaultValue = null;
|
||||
}
|
||||
|
||||
return new Ast\PhpDoc\MethodTagValueParameterNode($parameterType, $isReference, $isVariadic, $parameterName, $defaultValue);
|
||||
}
|
||||
|
||||
private function parseTemplateTagValue(TokenIterator $tokens, bool $parseDescription): Ast\PhpDoc\TemplateTagValueNode
|
||||
{
|
||||
$name = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
|
||||
if ($tokens->tryConsumeTokenValue('of') || $tokens->tryConsumeTokenValue('as')) {
|
||||
$bound = $this->typeParser->parse($tokens);
|
||||
|
||||
} else {
|
||||
$bound = null;
|
||||
}
|
||||
|
||||
if ($tokens->tryConsumeTokenValue('=')) {
|
||||
$default = $this->typeParser->parse($tokens);
|
||||
} else {
|
||||
$default = null;
|
||||
}
|
||||
|
||||
if ($parseDescription) {
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
} else {
|
||||
$description = '';
|
||||
}
|
||||
|
||||
return new Ast\PhpDoc\TemplateTagValueNode($name, $bound, $description, $default);
|
||||
}
|
||||
|
||||
private function parseExtendsTagValue(string $tagName, TokenIterator $tokens): Ast\PhpDoc\PhpDocTagValueNode
|
||||
{
|
||||
$baseType = new IdentifierTypeNode($tokens->currentTokenValue());
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
|
||||
$type = $this->typeParser->parseGeneric($tokens, $baseType);
|
||||
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
|
||||
switch ($tagName) {
|
||||
case '@extends':
|
||||
return new Ast\PhpDoc\ExtendsTagValueNode($type, $description);
|
||||
case '@implements':
|
||||
return new Ast\PhpDoc\ImplementsTagValueNode($type, $description);
|
||||
case '@use':
|
||||
return new Ast\PhpDoc\UsesTagValueNode($type, $description);
|
||||
}
|
||||
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
private function parseTypeAliasTagValue(TokenIterator $tokens): Ast\PhpDoc\TypeAliasTagValueNode
|
||||
{
|
||||
$alias = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
|
||||
// support psalm-type syntax
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL);
|
||||
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
|
||||
return new Ast\PhpDoc\TypeAliasTagValueNode($alias, $type);
|
||||
}
|
||||
|
||||
private function parseTypeAliasImportTagValue(TokenIterator $tokens): Ast\PhpDoc\TypeAliasImportTagValueNode
|
||||
{
|
||||
$importedAlias = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
|
||||
$tokens->consumeTokenValue(Lexer::TOKEN_IDENTIFIER, 'from');
|
||||
|
||||
$importedFrom = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
|
||||
$importedAs = null;
|
||||
if ($tokens->tryConsumeTokenValue('as')) {
|
||||
$importedAs = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
}
|
||||
|
||||
return new Ast\PhpDoc\TypeAliasImportTagValueNode($importedAlias, new IdentifierTypeNode($importedFrom), $importedAs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Ast\PhpDoc\AssertTagValueNode|Ast\PhpDoc\AssertTagPropertyValueNode|Ast\PhpDoc\AssertTagMethodValueNode
|
||||
*/
|
||||
private function parseAssertTagValue(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagValueNode
|
||||
{
|
||||
$isNegated = $tokens->tryConsumeTokenType(Lexer::TOKEN_NEGATED);
|
||||
$isEquality = $tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL);
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
$parameter = $this->parseAssertParameter($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
|
||||
if (array_key_exists('method', $parameter)) {
|
||||
return new Ast\PhpDoc\AssertTagMethodValueNode($type, $parameter['parameter'], $parameter['method'], $isNegated, $description, $isEquality);
|
||||
} elseif (array_key_exists('property', $parameter)) {
|
||||
return new Ast\PhpDoc\AssertTagPropertyValueNode($type, $parameter['parameter'], $parameter['property'], $isNegated, $description, $isEquality);
|
||||
}
|
||||
|
||||
return new Ast\PhpDoc\AssertTagValueNode($type, $parameter['parameter'], $isNegated, $description, $isEquality);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{parameter: string}|array{parameter: string, property: string}|array{parameter: string, method: string}
|
||||
*/
|
||||
private function parseAssertParameter(TokenIterator $tokens): array
|
||||
{
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_THIS_VARIABLE)) {
|
||||
$parameter = '$this';
|
||||
$requirePropertyOrMethod = true;
|
||||
$tokens->next();
|
||||
} else {
|
||||
$parameter = $tokens->currentTokenValue();
|
||||
$requirePropertyOrMethod = false;
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_VARIABLE);
|
||||
}
|
||||
|
||||
if ($requirePropertyOrMethod || $tokens->isCurrentTokenType(Lexer::TOKEN_ARROW)) {
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_ARROW);
|
||||
|
||||
$propertyOrMethod = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) {
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES);
|
||||
|
||||
return ['parameter' => $parameter, 'method' => $propertyOrMethod];
|
||||
}
|
||||
|
||||
return ['parameter' => $parameter, 'property' => $propertyOrMethod];
|
||||
}
|
||||
|
||||
return ['parameter' => $parameter];
|
||||
}
|
||||
|
||||
private function parseSelfOutTagValue(TokenIterator $tokens): Ast\PhpDoc\SelfOutTagValueNode
|
||||
{
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
|
||||
return new Ast\PhpDoc\SelfOutTagValueNode($type, $description);
|
||||
}
|
||||
|
||||
private function parseParamOutTagValue(TokenIterator $tokens): Ast\PhpDoc\ParamOutTagValueNode
|
||||
{
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
$parameterName = $this->parseRequiredVariableName($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
|
||||
return new Ast\PhpDoc\ParamOutTagValueNode($type, $parameterName, $description);
|
||||
}
|
||||
|
||||
private function parseOptionalVariableName(TokenIterator $tokens): string
|
||||
{
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_VARIABLE)) {
|
||||
$parameterName = $tokens->currentTokenValue();
|
||||
$tokens->next();
|
||||
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_THIS_VARIABLE)) {
|
||||
$parameterName = '$this';
|
||||
$tokens->next();
|
||||
|
||||
} else {
|
||||
$parameterName = '';
|
||||
}
|
||||
|
||||
return $parameterName;
|
||||
}
|
||||
|
||||
|
||||
private function parseRequiredVariableName(TokenIterator $tokens): string
|
||||
{
|
||||
$parameterName = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_VARIABLE);
|
||||
|
||||
return $parameterName;
|
||||
}
|
||||
|
||||
private function parseOptionalDescription(TokenIterator $tokens, bool $limitStartToken = false): string
|
||||
{
|
||||
if ($limitStartToken) {
|
||||
foreach (self::DISALLOWED_DESCRIPTION_START_TOKENS as $disallowedStartToken) {
|
||||
if (!$tokens->isCurrentTokenType($disallowedStartToken)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OTHER); // will throw exception
|
||||
}
|
||||
|
||||
if (
|
||||
$this->requireWhitespaceBeforeDescription
|
||||
&& !$tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END)
|
||||
&& !$tokens->isPrecededByHorizontalWhitespace()
|
||||
) {
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_HORIZONTAL_WS); // will throw exception
|
||||
}
|
||||
}
|
||||
|
||||
return $this->parseText($tokens)->text;
|
||||
}
|
||||
|
||||
}
|
||||
224
vendor/phpstan/phpdoc-parser/src/Parser/TokenIterator.php
vendored
Normal file
224
vendor/phpstan/phpdoc-parser/src/Parser/TokenIterator.php
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Parser;
|
||||
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use function array_pop;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function in_array;
|
||||
use function strlen;
|
||||
|
||||
class TokenIterator
|
||||
{
|
||||
|
||||
/** @var mixed[][] */
|
||||
private $tokens;
|
||||
|
||||
/** @var int */
|
||||
private $index;
|
||||
|
||||
/** @var int[] */
|
||||
private $savePoints = [];
|
||||
|
||||
public function __construct(array $tokens, int $index = 0)
|
||||
{
|
||||
$this->tokens = $tokens;
|
||||
$this->index = $index;
|
||||
|
||||
if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] !== Lexer::TOKEN_HORIZONTAL_WS) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->index++;
|
||||
}
|
||||
|
||||
|
||||
public function currentTokenValue(): string
|
||||
{
|
||||
return $this->tokens[$this->index][Lexer::VALUE_OFFSET];
|
||||
}
|
||||
|
||||
|
||||
public function currentTokenType(): int
|
||||
{
|
||||
return $this->tokens[$this->index][Lexer::TYPE_OFFSET];
|
||||
}
|
||||
|
||||
|
||||
public function currentTokenOffset(): int
|
||||
{
|
||||
$offset = 0;
|
||||
for ($i = 0; $i < $this->index; $i++) {
|
||||
$offset += strlen($this->tokens[$i][Lexer::VALUE_OFFSET]);
|
||||
}
|
||||
|
||||
return $offset;
|
||||
}
|
||||
|
||||
|
||||
public function isCurrentTokenValue(string $tokenValue): bool
|
||||
{
|
||||
return $this->tokens[$this->index][Lexer::VALUE_OFFSET] === $tokenValue;
|
||||
}
|
||||
|
||||
|
||||
public function isCurrentTokenType(int ...$tokenType): bool
|
||||
{
|
||||
return in_array($this->tokens[$this->index][Lexer::TYPE_OFFSET], $tokenType, true);
|
||||
}
|
||||
|
||||
|
||||
public function isPrecededByHorizontalWhitespace(): bool
|
||||
{
|
||||
return ($this->tokens[$this->index - 1][Lexer::TYPE_OFFSET] ?? -1) === Lexer::TOKEN_HORIZONTAL_WS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws ParserException
|
||||
*/
|
||||
public function consumeTokenType(int $tokenType): void
|
||||
{
|
||||
if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] !== $tokenType) {
|
||||
$this->throwError($tokenType);
|
||||
}
|
||||
|
||||
$this->index++;
|
||||
|
||||
if (($this->tokens[$this->index][Lexer::TYPE_OFFSET] ?? -1) !== Lexer::TOKEN_HORIZONTAL_WS) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->index++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws ParserException
|
||||
*/
|
||||
public function consumeTokenValue(int $tokenType, string $tokenValue): void
|
||||
{
|
||||
if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] !== $tokenType || $this->tokens[$this->index][Lexer::VALUE_OFFSET] !== $tokenValue) {
|
||||
$this->throwError($tokenType, $tokenValue);
|
||||
}
|
||||
|
||||
$this->index++;
|
||||
|
||||
if (($this->tokens[$this->index][Lexer::TYPE_OFFSET] ?? -1) !== Lexer::TOKEN_HORIZONTAL_WS) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->index++;
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
public function tryConsumeTokenValue(string $tokenValue): bool
|
||||
{
|
||||
if ($this->tokens[$this->index][Lexer::VALUE_OFFSET] !== $tokenValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->index++;
|
||||
|
||||
if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] === Lexer::TOKEN_HORIZONTAL_WS) {
|
||||
$this->index++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
public function tryConsumeTokenType(int $tokenType): bool
|
||||
{
|
||||
if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] !== $tokenType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->index++;
|
||||
|
||||
if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] === Lexer::TOKEN_HORIZONTAL_WS) {
|
||||
$this->index++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function getSkippedHorizontalWhiteSpaceIfAny(): string
|
||||
{
|
||||
if ($this->index > 0 && $this->tokens[$this->index - 1][Lexer::TYPE_OFFSET] === Lexer::TOKEN_HORIZONTAL_WS) {
|
||||
return $this->tokens[$this->index - 1][Lexer::VALUE_OFFSET];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
public function joinUntil(int ...$tokenType): string
|
||||
{
|
||||
$s = '';
|
||||
while (!in_array($this->tokens[$this->index][Lexer::TYPE_OFFSET], $tokenType, true)) {
|
||||
$s .= $this->tokens[$this->index++][Lexer::VALUE_OFFSET];
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
public function next(): void
|
||||
{
|
||||
$this->index++;
|
||||
|
||||
if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] !== Lexer::TOKEN_HORIZONTAL_WS) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->index++;
|
||||
}
|
||||
|
||||
/** @phpstan-impure */
|
||||
public function forwardToTheEnd(): void
|
||||
{
|
||||
$lastToken = count($this->tokens) - 1;
|
||||
$this->index = $lastToken;
|
||||
}
|
||||
|
||||
|
||||
public function pushSavePoint(): void
|
||||
{
|
||||
$this->savePoints[] = $this->index;
|
||||
}
|
||||
|
||||
|
||||
public function dropSavePoint(): void
|
||||
{
|
||||
array_pop($this->savePoints);
|
||||
}
|
||||
|
||||
|
||||
public function rollback(): void
|
||||
{
|
||||
$index = array_pop($this->savePoints);
|
||||
assert($index !== null);
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws ParserException
|
||||
*/
|
||||
private function throwError(int $expectedTokenType, ?string $expectedTokenValue = null): void
|
||||
{
|
||||
throw new ParserException(
|
||||
$this->currentTokenValue(),
|
||||
$this->currentTokenType(),
|
||||
$this->currentTokenOffset(),
|
||||
$expectedTokenType,
|
||||
$expectedTokenValue
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
585
vendor/phpstan/phpdoc-parser/src/Parser/TypeParser.php
vendored
Normal file
585
vendor/phpstan/phpdoc-parser/src/Parser/TypeParser.php
vendored
Normal file
@@ -0,0 +1,585 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Parser;
|
||||
|
||||
use LogicException;
|
||||
use PHPStan\PhpDocParser\Ast;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use function in_array;
|
||||
use function strpos;
|
||||
use function trim;
|
||||
|
||||
class TypeParser
|
||||
{
|
||||
|
||||
/** @var ConstExprParser|null */
|
||||
private $constExprParser;
|
||||
|
||||
public function __construct(?ConstExprParser $constExprParser = null)
|
||||
{
|
||||
$this->constExprParser = $constExprParser;
|
||||
}
|
||||
|
||||
/** @phpstan-impure */
|
||||
public function parse(TokenIterator $tokens): Ast\Type\TypeNode
|
||||
{
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_NULLABLE)) {
|
||||
$type = $this->parseNullable($tokens);
|
||||
|
||||
} else {
|
||||
$type = $this->parseAtomic($tokens);
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_UNION)) {
|
||||
$type = $this->parseUnion($tokens, $type);
|
||||
|
||||
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) {
|
||||
$type = $this->parseIntersection($tokens, $type);
|
||||
}
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function subParse(TokenIterator $tokens): Ast\Type\TypeNode
|
||||
{
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_NULLABLE)) {
|
||||
$type = $this->parseNullable($tokens);
|
||||
|
||||
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_VARIABLE)) {
|
||||
$type = $this->parseConditionalForParameter($tokens, $tokens->currentTokenValue());
|
||||
|
||||
} else {
|
||||
$type = $this->parseAtomic($tokens);
|
||||
|
||||
if ($tokens->isCurrentTokenValue('is')) {
|
||||
$type = $this->parseConditional($tokens, $type);
|
||||
} else {
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_UNION)) {
|
||||
$type = $this->subParseUnion($tokens, $type);
|
||||
|
||||
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) {
|
||||
$type = $this->subParseIntersection($tokens, $type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function parseAtomic(TokenIterator $tokens): Ast\Type\TypeNode
|
||||
{
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) {
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
$type = $this->subParse($tokens);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES);
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
|
||||
return $this->tryParseArrayOrOffsetAccess($tokens, $type);
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_THIS_VARIABLE)) {
|
||||
$type = new Ast\Type\ThisTypeNode();
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
|
||||
return $this->tryParseArrayOrOffsetAccess($tokens, $type);
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
$currentTokenValue = $tokens->currentTokenValue();
|
||||
$tokens->pushSavePoint(); // because of ConstFetchNode
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_IDENTIFIER)) {
|
||||
$type = new Ast\Type\IdentifierTypeNode($currentTokenValue);
|
||||
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_COLON)) {
|
||||
$tokens->dropSavePoint(); // because of ConstFetchNode
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) {
|
||||
$tokens->pushSavePoint();
|
||||
|
||||
$isHtml = $this->isHtml($tokens);
|
||||
$tokens->rollback();
|
||||
if ($isHtml) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
$type = $this->parseGeneric($tokens, $type);
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
|
||||
$type = $this->tryParseArrayOrOffsetAccess($tokens, $type);
|
||||
}
|
||||
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) {
|
||||
$type = $this->tryParseCallable($tokens, $type);
|
||||
|
||||
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
|
||||
$type = $this->tryParseArrayOrOffsetAccess($tokens, $type);
|
||||
|
||||
} elseif (in_array($type->name, ['array', 'list'], true) && $tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET) && !$tokens->isPrecededByHorizontalWhitespace()) {
|
||||
$type = $this->parseArrayShape($tokens, $type, $type->name);
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
|
||||
$type = $this->tryParseArrayOrOffsetAccess($tokens, $type);
|
||||
}
|
||||
}
|
||||
|
||||
return $type;
|
||||
} else {
|
||||
$tokens->rollback(); // because of ConstFetchNode
|
||||
}
|
||||
} else {
|
||||
$tokens->dropSavePoint(); // because of ConstFetchNode
|
||||
}
|
||||
|
||||
$exception = new ParserException(
|
||||
$tokens->currentTokenValue(),
|
||||
$tokens->currentTokenType(),
|
||||
$tokens->currentTokenOffset(),
|
||||
Lexer::TOKEN_IDENTIFIER
|
||||
);
|
||||
|
||||
if ($this->constExprParser === null) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
try {
|
||||
$constExpr = $this->constExprParser->parse($tokens, true);
|
||||
if ($constExpr instanceof Ast\ConstExpr\ConstExprArrayNode) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return new Ast\Type\ConstTypeNode($constExpr);
|
||||
} catch (LogicException $e) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function parseUnion(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode
|
||||
{
|
||||
$types = [$type];
|
||||
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_UNION)) {
|
||||
$types[] = $this->parseAtomic($tokens);
|
||||
}
|
||||
|
||||
return new Ast\Type\UnionTypeNode($types);
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function subParseUnion(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode
|
||||
{
|
||||
$types = [$type];
|
||||
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_UNION)) {
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
$types[] = $this->parseAtomic($tokens);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
}
|
||||
|
||||
return new Ast\Type\UnionTypeNode($types);
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function parseIntersection(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode
|
||||
{
|
||||
$types = [$type];
|
||||
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)) {
|
||||
$types[] = $this->parseAtomic($tokens);
|
||||
}
|
||||
|
||||
return new Ast\Type\IntersectionTypeNode($types);
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function subParseIntersection(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode
|
||||
{
|
||||
$types = [$type];
|
||||
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)) {
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
$types[] = $this->parseAtomic($tokens);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
}
|
||||
|
||||
return new Ast\Type\IntersectionTypeNode($types);
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function parseConditional(TokenIterator $tokens, Ast\Type\TypeNode $subjectType): Ast\Type\TypeNode
|
||||
{
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
|
||||
$negated = false;
|
||||
if ($tokens->isCurrentTokenValue('not')) {
|
||||
$negated = true;
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
}
|
||||
|
||||
$targetType = $this->parse($tokens);
|
||||
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_NULLABLE);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
$ifType = $this->parse($tokens);
|
||||
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_COLON);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
$elseType = $this->subParse($tokens);
|
||||
|
||||
return new Ast\Type\ConditionalTypeNode($subjectType, $targetType, $ifType, $elseType, $negated);
|
||||
}
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function parseConditionalForParameter(TokenIterator $tokens, string $parameterName): Ast\Type\TypeNode
|
||||
{
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_VARIABLE);
|
||||
$tokens->consumeTokenValue(Lexer::TOKEN_IDENTIFIER, 'is');
|
||||
|
||||
$negated = false;
|
||||
if ($tokens->isCurrentTokenValue('not')) {
|
||||
$negated = true;
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
}
|
||||
|
||||
$targetType = $this->parse($tokens);
|
||||
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_NULLABLE);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
$ifType = $this->parse($tokens);
|
||||
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_COLON);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
$elseType = $this->subParse($tokens);
|
||||
|
||||
return new Ast\Type\ConditionalTypeForParameterNode($parameterName, $targetType, $ifType, $elseType, $negated);
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function parseNullable(TokenIterator $tokens): Ast\Type\TypeNode
|
||||
{
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_NULLABLE);
|
||||
|
||||
$type = $this->parseAtomic($tokens);
|
||||
|
||||
return new Ast\Type\NullableTypeNode($type);
|
||||
}
|
||||
|
||||
/** @phpstan-impure */
|
||||
public function isHtml(TokenIterator $tokens): bool
|
||||
{
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET);
|
||||
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$htmlTagName = $tokens->currentTokenValue();
|
||||
|
||||
$tokens->next();
|
||||
|
||||
if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!$tokens->isCurrentTokenType(Lexer::TOKEN_END)) {
|
||||
if (
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)
|
||||
&& strpos($tokens->currentTokenValue(), '/' . $htmlTagName . '>') !== false
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$tokens->next();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @phpstan-impure */
|
||||
public function parseGeneric(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $baseType): Ast\Type\GenericTypeNode
|
||||
{
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
$genericTypes = [];
|
||||
$variances = [];
|
||||
|
||||
[$genericTypes[], $variances[]] = $this->parseGenericTypeArgument($tokens);
|
||||
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET)) {
|
||||
// trailing comma case
|
||||
return new Ast\Type\GenericTypeNode($baseType, $genericTypes, $variances);
|
||||
}
|
||||
[$genericTypes[], $variances[]] = $this->parseGenericTypeArgument($tokens);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
}
|
||||
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET);
|
||||
|
||||
return new Ast\Type\GenericTypeNode($baseType, $genericTypes, $variances);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @phpstan-impure
|
||||
* @return array{Ast\Type\TypeNode, Ast\Type\GenericTypeNode::VARIANCE_*}
|
||||
*/
|
||||
public function parseGenericTypeArgument(TokenIterator $tokens): array
|
||||
{
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_WILDCARD)) {
|
||||
return [
|
||||
new Ast\Type\IdentifierTypeNode('mixed'),
|
||||
Ast\Type\GenericTypeNode::VARIANCE_BIVARIANT,
|
||||
];
|
||||
}
|
||||
|
||||
if ($tokens->tryConsumeTokenValue('contravariant')) {
|
||||
$variance = Ast\Type\GenericTypeNode::VARIANCE_CONTRAVARIANT;
|
||||
} elseif ($tokens->tryConsumeTokenValue('covariant')) {
|
||||
$variance = Ast\Type\GenericTypeNode::VARIANCE_COVARIANT;
|
||||
} else {
|
||||
$variance = Ast\Type\GenericTypeNode::VARIANCE_INVARIANT;
|
||||
}
|
||||
|
||||
$type = $this->parse($tokens);
|
||||
return [$type, $variance];
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function parseCallable(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $identifier): Ast\Type\TypeNode
|
||||
{
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
$parameters = [];
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) {
|
||||
$parameters[] = $this->parseCallableParameter($tokens);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) {
|
||||
break;
|
||||
}
|
||||
$parameters[] = $this->parseCallableParameter($tokens);
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_COLON);
|
||||
$returnType = $this->parseCallableReturnType($tokens);
|
||||
|
||||
return new Ast\Type\CallableTypeNode($identifier, $parameters, $returnType);
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function parseCallableParameter(TokenIterator $tokens): Ast\Type\CallableTypeParameterNode
|
||||
{
|
||||
$type = $this->parse($tokens);
|
||||
$isReference = $tokens->tryConsumeTokenType(Lexer::TOKEN_REFERENCE);
|
||||
$isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC);
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_VARIABLE)) {
|
||||
$parameterName = $tokens->currentTokenValue();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_VARIABLE);
|
||||
|
||||
} else {
|
||||
$parameterName = '';
|
||||
}
|
||||
|
||||
$isOptional = $tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL);
|
||||
return new Ast\Type\CallableTypeParameterNode($type, $isReference, $isVariadic, $parameterName, $isOptional);
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function parseCallableReturnType(TokenIterator $tokens): Ast\Type\TypeNode
|
||||
{
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_NULLABLE)) {
|
||||
$type = $this->parseNullable($tokens);
|
||||
|
||||
} elseif ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) {
|
||||
$type = $this->parse($tokens);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES);
|
||||
|
||||
} else {
|
||||
$type = new Ast\Type\IdentifierTypeNode($tokens->currentTokenValue());
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) {
|
||||
$type = $this->parseGeneric($tokens, $type);
|
||||
|
||||
} elseif (in_array($type->name, ['array', 'list'], true) && $tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET) && !$tokens->isPrecededByHorizontalWhitespace()) {
|
||||
$type = $this->parseArrayShape($tokens, $type, $type->name);
|
||||
}
|
||||
}
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
|
||||
$type = $this->tryParseArrayOrOffsetAccess($tokens, $type);
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function tryParseCallable(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $identifier): Ast\Type\TypeNode
|
||||
{
|
||||
try {
|
||||
$tokens->pushSavePoint();
|
||||
$type = $this->parseCallable($tokens, $identifier);
|
||||
$tokens->dropSavePoint();
|
||||
|
||||
} catch (ParserException $e) {
|
||||
$tokens->rollback();
|
||||
$type = $identifier;
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function tryParseArrayOrOffsetAccess(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode
|
||||
{
|
||||
try {
|
||||
while ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
|
||||
$tokens->pushSavePoint();
|
||||
|
||||
$canBeOffsetAccessType = !$tokens->isPrecededByHorizontalWhitespace();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET);
|
||||
|
||||
if ($canBeOffsetAccessType && !$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_SQUARE_BRACKET)) {
|
||||
$offset = $this->parse($tokens);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_SQUARE_BRACKET);
|
||||
$tokens->dropSavePoint();
|
||||
$type = new Ast\Type\OffsetAccessTypeNode($type, $offset);
|
||||
} else {
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_SQUARE_BRACKET);
|
||||
$tokens->dropSavePoint();
|
||||
$type = new Ast\Type\ArrayTypeNode($type);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (ParserException $e) {
|
||||
$tokens->rollback();
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @phpstan-impure
|
||||
* @param Ast\Type\ArrayShapeNode::KIND_* $kind
|
||||
*/
|
||||
private function parseArrayShape(TokenIterator $tokens, Ast\Type\TypeNode $type, string $kind): Ast\Type\ArrayShapeNode
|
||||
{
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET);
|
||||
|
||||
$items = [];
|
||||
$sealed = true;
|
||||
|
||||
do {
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
|
||||
return new Ast\Type\ArrayShapeNode($items, true, $kind);
|
||||
}
|
||||
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC)) {
|
||||
$sealed = false;
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA);
|
||||
break;
|
||||
}
|
||||
|
||||
$items[] = $this->parseArrayShapeItem($tokens);
|
||||
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
} while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA));
|
||||
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET);
|
||||
|
||||
return new Ast\Type\ArrayShapeNode($items, $sealed, $kind);
|
||||
}
|
||||
|
||||
|
||||
/** @phpstan-impure */
|
||||
private function parseArrayShapeItem(TokenIterator $tokens): Ast\Type\ArrayShapeItemNode
|
||||
{
|
||||
try {
|
||||
$tokens->pushSavePoint();
|
||||
$key = $this->parseArrayShapeKey($tokens);
|
||||
$optional = $tokens->tryConsumeTokenType(Lexer::TOKEN_NULLABLE);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_COLON);
|
||||
$value = $this->parse($tokens);
|
||||
$tokens->dropSavePoint();
|
||||
|
||||
return new Ast\Type\ArrayShapeItemNode($key, $optional, $value);
|
||||
} catch (ParserException $e) {
|
||||
$tokens->rollback();
|
||||
$value = $this->parse($tokens);
|
||||
|
||||
return new Ast\Type\ArrayShapeItemNode(null, false, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-impure
|
||||
* @return Ast\ConstExpr\ConstExprIntegerNode|Ast\ConstExpr\ConstExprStringNode|Ast\Type\IdentifierTypeNode
|
||||
*/
|
||||
private function parseArrayShapeKey(TokenIterator $tokens)
|
||||
{
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_INTEGER)) {
|
||||
$key = new Ast\ConstExpr\ConstExprIntegerNode($tokens->currentTokenValue());
|
||||
$tokens->next();
|
||||
|
||||
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING)) {
|
||||
$key = new Ast\ConstExpr\ConstExprStringNode(trim($tokens->currentTokenValue(), "'"));
|
||||
$tokens->next();
|
||||
|
||||
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_QUOTED_STRING)) {
|
||||
$key = new Ast\ConstExpr\ConstExprStringNode(trim($tokens->currentTokenValue(), '"'));
|
||||
$tokens->next();
|
||||
|
||||
} else {
|
||||
$key = new Ast\Type\IdentifierTypeNode($tokens->currentTokenValue());
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user