Phpstan to max level

This commit is contained in:
Jaapio
2019-09-20 16:52:17 +02:00
parent aee984014b
commit 19a1f3a91f
21 changed files with 156 additions and 102 deletions
+25 -32
View File
@@ -14,6 +14,7 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\Types\Context as TypeContext;
use Webmozart\Assert\Assert;
use const PREG_SPLIT_DELIM_CAPTURE;
use function count;
use function explode;
@@ -62,9 +63,28 @@ class DescriptionFactory
*/
public function create(string $contents, ?TypeContext $context = null) : Description
{
[$text, $tags] = $this->parse($this->lex($contents), $context);
$tokens = $this->lex($contents);
$count = count($tokens);
$tagCount = 0;
$tags = [];
return new Description($text, $tags);
for ($i = 1; $i < $count; $i += 2) {
$tag = $this->tagFactory->create($tokens[$i], $context);
if ($tag !== null) {
$tags[] = $tag;
}
$tokens[$i] = '%' . ++$tagCount . '$s';
}
//In order to allow "literal" inline tags, the otherwise invalid
//sequence "{@}" is changed to "@", and "{}" is changed to "}".
//"%" is escaped to "%%" because of vsprintf.
//See unit tests for examples.
for ($i = 0; $i < $count; $i += 2) {
$tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]);
}
return new Description(implode('', $tokens), $tags);
}
/**
@@ -81,7 +101,7 @@ class DescriptionFactory
return [$contents];
}
return preg_split(
$parts = preg_split(
'/\{
# "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally.
(?!@\})
@@ -110,35 +130,8 @@ class DescriptionFactory
0,
PREG_SPLIT_DELIM_CAPTURE
);
}
/**
* Parses the stream of tokens in to a new set of tokens containing Tags.
*
* @param string[] $tokens
*
* @return string[]|Tag[]
*/
private function parse(array $tokens, ?TypeContext $context = null) : array
{
$count = count($tokens);
$tagCount = 0;
$tags = [];
for ($i = 1; $i < $count; $i += 2) {
$tags[] = $this->tagFactory->create($tokens[$i], $context);
$tokens[$i] = '%' . ++$tagCount . '$s';
}
//In order to allow "literal" inline tags, the otherwise invalid
//sequence "{@}" is changed to "@", and "{}" is changed to "}".
//"%" is escaped to "%%" because of vsprintf.
//See unit tests for examples.
for ($i = 0; $i < $count; $i += 2) {
$tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]);
}
return [implode('', $tokens), $tags];
Assert::isArray($parts);
return $parts;
}
/**
+5 -2
View File
@@ -96,8 +96,10 @@ class ExampleFinder
* 2. Checks the source folder for the given filename
* 3. Checks the 'examples' folder in the current working directory for examples
* 4. Checks the path relative to the current working directory for the given filename
*
* @return string[] all lines of the example file
*/
private function getExampleFileContents(string $filename) : ?string
private function getExampleFileContents(string $filename) : ?array
{
$normalizedPath = null;
@@ -119,7 +121,8 @@ class ExampleFinder
}
}
return $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : null;
$lines = $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : false;
return $lines !== false ? $lines : null;
}
/**
+39 -20
View File
@@ -28,6 +28,23 @@ use function count;
use function get_class;
use function preg_match;
use function strpos;
use phpDocumentor\Reflection\DocBlock\Tags\Author;
use phpDocumentor\Reflection\DocBlock\Tags\Covers;
use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
use phpDocumentor\Reflection\DocBlock\Tags\Link;
use phpDocumentor\Reflection\DocBlock\Tags\Method;
use phpDocumentor\Reflection\DocBlock\Tags\Param;
use phpDocumentor\Reflection\DocBlock\Tags\PropertyRead;
use phpDocumentor\Reflection\DocBlock\Tags\Property;
use phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite;
use phpDocumentor\Reflection\DocBlock\Tags\Return_;
use phpDocumentor\Reflection\DocBlock\Tags\See;
use phpDocumentor\Reflection\DocBlock\Tags\Since;
use phpDocumentor\Reflection\DocBlock\Tags\Source;
use phpDocumentor\Reflection\DocBlock\Tags\Throws;
use phpDocumentor\Reflection\DocBlock\Tags\Uses;
use phpDocumentor\Reflection\DocBlock\Tags\Var_;
use phpDocumentor\Reflection\DocBlock\Tags\Version;
/**
* Creates a Tag object given the contents of a tag.
@@ -56,25 +73,25 @@ final class StandardTagFactory implements TagFactory
* FQCN to a class that handles it as an array value.
*/
private $tagHandlerMappings = [
'author' => '\phpDocumentor\Reflection\DocBlock\Tags\Author',
'covers' => '\phpDocumentor\Reflection\DocBlock\Tags\Covers',
'deprecated' => '\phpDocumentor\Reflection\DocBlock\Tags\Deprecated',
'author' => Author::class,
'covers' => Covers::class,
'deprecated' => Deprecated::class,
// 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example',
'link' => '\phpDocumentor\Reflection\DocBlock\Tags\Link',
'method' => '\phpDocumentor\Reflection\DocBlock\Tags\Method',
'param' => '\phpDocumentor\Reflection\DocBlock\Tags\Param',
'property-read' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyRead',
'property' => '\phpDocumentor\Reflection\DocBlock\Tags\Property',
'property-write' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite',
'return' => '\phpDocumentor\Reflection\DocBlock\Tags\Return_',
'see' => '\phpDocumentor\Reflection\DocBlock\Tags\See',
'since' => '\phpDocumentor\Reflection\DocBlock\Tags\Since',
'source' => '\phpDocumentor\Reflection\DocBlock\Tags\Source',
'throw' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws',
'throws' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws',
'uses' => '\phpDocumentor\Reflection\DocBlock\Tags\Uses',
'var' => '\phpDocumentor\Reflection\DocBlock\Tags\Var_',
'version' => '\phpDocumentor\Reflection\DocBlock\Tags\Version',
'link' => Link::class,
'method' => Method::class,
'param' => Param::class,
'property-read' => PropertyRead::class,
'property' => Property::class,
'property-write' => PropertyWrite::class,
'return' => Return_::class,
'see' => See::class,
'since' => Since::class,
'source' => Source::class,
'throw' => Throws::class,
'throws' => Throws::class,
'uses' => Uses::class,
'var' => Var_::class,
'version' => Version::class,
];
/**
@@ -149,7 +166,7 @@ final class StandardTagFactory implements TagFactory
/**
* {@inheritDoc}
*/
public function addService($service, $alias = null) : void
public function addService(object $service, $alias = null) : void
{
$this->serviceLocator[$alias ?: get_class($service)] = $service;
}
@@ -215,6 +232,8 @@ final class StandardTagFactory implements TagFactory
/**
* Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`).
*
* @return
*/
private function findHandlerClassName(string $tagName, TypeContext $context) : string
{
@@ -245,7 +264,7 @@ final class StandardTagFactory implements TagFactory
{
$arguments = [];
foreach ($parameters as $parameter) {
$typeHint = $parameter->getClass() ? $parameter->getClass()->getName() : null;
$typeHint = $parameter->getClass() !== null ? $parameter->getClass()->getName() : null;
if (isset($locator[$typeHint])) {
$arguments[] = $locator[$typeHint];
continue;
+3
View File
@@ -51,8 +51,11 @@ final class Covers extends BaseTag implements Factory\StaticMethod
?TypeContext $context = null
) : self {
Assert::notEmpty($body);
Assert::notNull($descriptionFactory);
Assert::notNull($resolver);
$parts = preg_split('/\s+/Su', $body, 2);
Assert::isArray($parts);
return new static(
$resolver->resolve($parts[0], $context),
+2 -1
View File
@@ -43,7 +43,7 @@ final class Deprecated extends BaseTag implements Factory\StaticMethod
[^\s\:]+\:\s*\$[^\$]+\$
)';
/** @var string The version vector. */
/** @var string|null The version vector. */
private $version = '';
public function __construct(?string $version = null, ?Description $description = null)
@@ -74,6 +74,7 @@ final class Deprecated extends BaseTag implements Factory\StaticMethod
);
}
Assert::notNull($descriptionFactory);
return new static(
$matches[1],
$descriptionFactory->create($matches[2] ?? '', $context)
+1 -1
View File
@@ -54,7 +54,7 @@ class Generic extends BaseTag implements Factory\StaticMethod
Assert::stringNotEmpty($name);
Assert::notNull($descriptionFactory);
$description = $descriptionFactory && $body !== '' ? $descriptionFactory->create($body, $context) : null;
$description = $body !== '' ? $descriptionFactory->create($body, $context) : null;
return new static($name, $description);
}
+1
View File
@@ -50,6 +50,7 @@ final class Link extends BaseTag implements Factory\StaticMethod
Assert::notNull($descriptionFactory);
$parts = preg_split('/\s+/Su', $body, 2);
Assert::isArray($parts);
$description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;
return new static($parts[0], $description);
+5 -4
View File
@@ -44,7 +44,7 @@ final class Method extends BaseTag implements Factory\StaticMethod
/** @var string */
private $methodName = '';
/** @var string[] */
/** @var string[][] */
private $arguments = [];
/** @var bool */
@@ -87,7 +87,8 @@ final class Method extends BaseTag implements Factory\StaticMethod
?TypeContext $context = null
) : ?self {
Assert::stringNotEmpty($body);
Assert::allNotNull([$typeResolver, $descriptionFactory]);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
// 1. none or more whitespace
// 2. optionally the keyword "static" followed by whitespace
@@ -184,7 +185,7 @@ final class Method extends BaseTag implements Factory\StaticMethod
}
/**
* @return string[]
* @return string[][]
*/
public function getArguments() : array
{
@@ -221,7 +222,7 @@ final class Method extends BaseTag implements Factory\StaticMethod
}
/**
* @param mixed[][] $arguments
* @param array<string|mixed[]> $arguments
*
* @return mixed[][]
*/
+7 -5
View File
@@ -66,32 +66,34 @@ final class Param extends BaseTag implements Factory\StaticMethod
?TypeContext $context = null
) : self {
Assert::stringNotEmpty($body);
Assert::allNotNull([$typeResolver, $descriptionFactory]);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
$parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
Assert::isArray($parts);
$type = null;
$variableName = '';
$isVariadic = false;
// if the first item that is encountered is not a variable; it is a type
if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
if (isset($parts[0]) && ($parts[0] !== '') && ($parts[0][0] !== '$')) {
$type = $typeResolver->resolve(array_shift($parts), $context);
array_shift($parts);
}
// if the next item starts with a $ or ...$ it must be the variable name
if (isset($parts[0]) && (strlen($parts[0]) > 0) &&
if (isset($parts[0]) && ($parts[0] !== '') &&
(strpos($parts[0], '$') === 0 || strpos($parts[0], '...$') === 0)
) {
$variableName = array_shift($parts);
array_shift($parts);
if (substr($variableName, 0, 3) === '...') {
if ($variableName !== null && strpos($variableName, '...') === 0) {
$isVariadic = true;
$variableName = substr($variableName, 3);
}
if (substr($variableName, 0, 1) === '$') {
if ($variableName !== null && strpos($variableName, '$') === 0) {
$variableName = substr($variableName, 1);
}
}
+8 -6
View File
@@ -23,7 +23,7 @@ use const PREG_SPLIT_DELIM_CAPTURE;
use function array_shift;
use function implode;
use function preg_split;
use function strlen;
use function strpos;
use function substr;
/**
@@ -57,24 +57,26 @@ class Property extends BaseTag implements Factory\StaticMethod
?TypeContext $context = null
) : self {
Assert::stringNotEmpty($body);
Assert::allNotNull([$typeResolver, $descriptionFactory]);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
$parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
$parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
Assert::isArray($parts);
$type = null;
$variableName = '';
// if the first item that is encountered is not a variable; it is a type
if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
if (isset($parts[0]) && ($parts[0] !== '') && ($parts[0][0] !== '$')) {
$type = $typeResolver->resolve(array_shift($parts), $context);
array_shift($parts);
}
// if the next item starts with a $ or ...$ it must be the variable name
if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
if (isset($parts[0]) && ($parts[0] !== '') && (strpos($parts[0], '$') === 0)) {
$variableName = array_shift($parts);
array_shift($parts);
if (substr($variableName, 0, 1) === '$') {
if ($variableName !== null && strpos($variableName, '$') === 0) {
$variableName = substr($variableName, 1);
}
}
+6 -4
View File
@@ -57,24 +57,26 @@ class PropertyRead extends BaseTag implements Factory\StaticMethod
?TypeContext $context = null
) : self {
Assert::stringNotEmpty($body);
Assert::allNotNull([$typeResolver, $descriptionFactory]);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
$parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
Assert::isArray($parts);
$type = null;
$variableName = '';
// if the first item that is encountered is not a variable; it is a type
if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
if (isset($parts[0]) && ($parts[0] !== '') && ($parts[0][0] !== '$')) {
$type = $typeResolver->resolve(array_shift($parts), $context);
array_shift($parts);
}
// if the next item starts with a $ or ...$ it must be the variable name
if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
if (isset($parts[0]) && ($parts[0] !== '') && (strpos($parts[0], '$') === 0)) {
$variableName = array_shift($parts);
array_shift($parts);
if (substr($variableName, 0, 1) === '$') {
if ($variableName !== null && strpos($variableName, '$') === 0) {
$variableName = substr($variableName, 1);
}
}
+6 -3
View File
@@ -24,6 +24,7 @@ use function array_shift;
use function implode;
use function preg_split;
use function strlen;
use function strpos;
use function substr;
/**
@@ -57,14 +58,16 @@ class PropertyWrite extends BaseTag implements Factory\StaticMethod
?TypeContext $context = null
) : self {
Assert::stringNotEmpty($body);
Assert::allNotNull([$typeResolver, $descriptionFactory]);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
$parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
Assert::isArray($parts);
$type = null;
$variableName = '';
// if the first item that is encountered is not a variable; it is a type
if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
if (isset($parts[0]) && ($parts[0] !== '') && ($parts[0][0] !== '$')) {
$type = $typeResolver->resolve(array_shift($parts), $context);
array_shift($parts);
}
@@ -74,7 +77,7 @@ class PropertyWrite extends BaseTag implements Factory\StaticMethod
$variableName = array_shift($parts);
array_shift($parts);
if (substr($variableName, 0, 1) === '$') {
if ($variableName !== null && strpos($variableName, '$') === 0) {
$variableName = substr($variableName, 1);
}
}
+3 -1
View File
@@ -47,9 +47,11 @@ final class Return_ extends BaseTag implements Factory\StaticMethod
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
) : self {
Assert::allNotNull([$typeResolver, $descriptionFactory]);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
$parts = preg_split('/\s+/Su', $body, 2);
Assert::isArray($parts);
$type = $typeResolver->resolve($parts[0] ?? '', $context);
$description = $descriptionFactory->create($parts[1] ?? '', $context);
+5 -3
View File
@@ -49,13 +49,15 @@ class See extends BaseTag implements Factory\StaticMethod
*/
public static function create(
string $body,
?FqsenResolver $resolver = null,
?FqsenResolver $typeResolver = null,
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
) : self {
Assert::allNotNull([$resolver, $descriptionFactory]);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
$parts = preg_split('/\s+/Su', $body, 2);
Assert::isArray($parts);
$description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;
// https://tools.ietf.org/html/rfc2396#section-3
@@ -63,7 +65,7 @@ class See extends BaseTag implements Factory\StaticMethod
return new static(new Url($parts[0]), $description);
}
return new static(new FqsenRef($resolver->resolve($parts[0], $context)), $description);
return new static(new FqsenRef($typeResolver->resolve($parts[0], $context)), $description);
}
/**
+2 -1
View File
@@ -43,7 +43,7 @@ final class Since extends BaseTag implements Factory\StaticMethod
[^\s\:]+\:\s*\$[^\$]+\$
)';
/** @var string The version vector. */
/** @var string|null The version vector. */
private $version = '';
public function __construct(?string $version = null, ?Description $description = null)
@@ -68,6 +68,7 @@ final class Since extends BaseTag implements Factory\StaticMethod
return null;
}
Assert::notNull($descriptionFactory);
return new static(
$matches[1],
$descriptionFactory->create($matches[2] ?? '', $context)
+3 -1
View File
@@ -47,9 +47,11 @@ final class Throws extends BaseTag implements Factory\StaticMethod
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
) : self {
Assert::allNotNull([$typeResolver, $descriptionFactory]);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
$parts = preg_split('/\s+/Su', $body, 2);
Assert::isArray($parts);
$type = $typeResolver->resolve($parts[0] ?? '', $context);
$description = $descriptionFactory->create($parts[1] ?? '', $context);
+4 -1
View File
@@ -50,9 +50,12 @@ final class Uses extends BaseTag implements Factory\StaticMethod
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
) : self {
Assert::allNotNull([$resolver, $descriptionFactory]);
Assert::notNull($resolver);
Assert::notNull($descriptionFactory);
$parts = preg_split('/\s+/Su', $body, 2);
Assert::isArray($parts);
Assert::allString($parts);
return new static(
$resolver->resolve($parts[0], $context),
+10 -5
View File
@@ -57,24 +57,29 @@ class Var_ extends BaseTag implements Factory\StaticMethod
?TypeContext $context = null
) : self {
Assert::stringNotEmpty($body);
Assert::allNotNull([$typeResolver, $descriptionFactory]);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
$parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
Assert::isArray($parts);
Assert::allString($parts);
$type = null;
$variableName = '';
// if the first item that is encountered is not a variable; it is a type
if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
$type = $typeResolver->resolve(array_shift($parts), $context);
if (isset($parts[0]) && ($parts[0] !== '') && ($parts[0][0] !== '$')) {
if ($typeResolver !== null) {
$type = $typeResolver->resolve(array_shift($parts), $context);
}
array_shift($parts);
}
// if the next item starts with a $ or ...$ it must be the variable name
if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
if (isset($parts[0]) && ($parts[0] !== '') && (strpos($parts[0], '$') === 0)) {
$variableName = array_shift($parts);
array_shift($parts);
if (substr($variableName, 0, 1) === '$') {
if ($variableName !== null && strpos($variableName, '$') === 0) {
$variableName = substr($variableName, 1);
}
}
+7 -2
View File
@@ -43,7 +43,7 @@ final class Version extends BaseTag implements Factory\StaticMethod
[^\s\:]+\:\s*\$[^\$]+\$
)';
/** @var string The version vector. */
/** @var string|null The version vector. */
private $version = '';
public function __construct(?string $version = null, ?Description $description = null)
@@ -68,9 +68,14 @@ final class Version extends BaseTag implements Factory\StaticMethod
return null;
}
$description = null;
if ($descriptionFactory !== null) {
$description = $descriptionFactory->create($matches[2] ?? '', $context);
}
return new static(
$matches[1],
$descriptionFactory->create($matches[2] ?? '', $context)
$description
);
}