Skip to content

Commit

Permalink
Support messages on the deprecated PhpDoc tag
Browse files Browse the repository at this point in the history
  • Loading branch information
mglaman committed Mar 12, 2019
1 parent d56dc3e commit 6b325ac
Show file tree
Hide file tree
Showing 22 changed files with 238 additions and 53 deletions.
10 changes: 7 additions & 3 deletions src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ private function processStmtNode(
$scope = $scope->enterDeclareStrictTypes();
}
} elseif ($stmt instanceof Node\Stmt\Function_) {
[$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $isDeprecated, $isInternal, $isFinal] = $this->getPhpDocs($scope, $stmt);
[$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal] = $this->getPhpDocs($scope, $stmt);

foreach ($stmt->params as $param) {
$this->processParamNode($param, $scope, $nodeCallback);
Expand All @@ -252,13 +252,14 @@ private function processStmtNode(
$phpDocParameterTypes,
$phpDocReturnType,
$phpDocThrowType,
$deprecatedDescription,
$isDeprecated,
$isInternal,
$isFinal
);
$this->processStmtNodes($stmt->stmts, $functionScope, $nodeCallback);
} elseif ($stmt instanceof Node\Stmt\ClassMethod) {
[$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $isDeprecated, $isInternal, $isFinal] = $this->getPhpDocs($scope, $stmt);
[$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal] = $this->getPhpDocs($scope, $stmt);

foreach ($stmt->params as $param) {
$this->processParamNode($param, $scope, $nodeCallback);
Expand All @@ -273,6 +274,7 @@ private function processStmtNode(
$phpDocParameterTypes,
$phpDocReturnType,
$phpDocThrowType,
$deprecatedDescription,
$isDeprecated,
$isInternal,
$isFinal
Expand Down Expand Up @@ -2016,6 +2018,7 @@ private function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): arra
$phpDocParameterTypes = [];
$phpDocReturnType = null;
$phpDocThrowType = null;
$deprecatedDescription = null;
$isDeprecated = false;
$isInternal = false;
$isFinal = false;
Expand Down Expand Up @@ -2071,12 +2074,13 @@ private function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): arra
$phpDocReturnType = $resolvedPhpDoc->getReturnTag()->getType();
}
$phpDocThrowType = $resolvedPhpDoc->getThrowsTag() !== null ? $resolvedPhpDoc->getThrowsTag()->getType() : null;
$deprecatedDescription = $resolvedPhpDoc->getDeprecatedTag() !== null ? $resolvedPhpDoc->getDeprecatedTag()->getMessage(): null;
$isDeprecated = $resolvedPhpDoc->isDeprecated();
$isInternal = $resolvedPhpDoc->isInternal();
$isFinal = $resolvedPhpDoc->isFinal();
}

return [$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $isDeprecated, $isInternal, $isFinal];
return [$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal];
}

}
6 changes: 6 additions & 0 deletions src/Analyser/Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -1773,6 +1773,7 @@ public function enterTrait(ClassReflection $traitReflection): self
* @param Type[] $phpDocParameterTypes
* @param Type|null $phpDocReturnType
* @param Type|null $throwType
* @param string|null $deprecatedDescription
* @param bool $isDeprecated
* @param bool $isInternal
* @param bool $isFinal
Expand All @@ -1783,6 +1784,7 @@ public function enterClassMethod(
array $phpDocParameterTypes,
?Type $phpDocReturnType,
?Type $throwType,
?string $deprecatedDescription,
bool $isDeprecated,
bool $isInternal,
bool $isFinal
Expand All @@ -1802,6 +1804,7 @@ public function enterClassMethod(
$this->getFunctionType($classMethod->returnType, $classMethod->returnType === null, false),
$phpDocReturnType,
$throwType,
$deprecatedDescription,
$isDeprecated,
$isInternal,
$isFinal
Expand Down Expand Up @@ -1835,6 +1838,7 @@ private function getRealParameterTypes(Node\FunctionLike $functionLike): array
* @param Type[] $phpDocParameterTypes
* @param Type|null $phpDocReturnType
* @param Type|null $throwType
* @param string|null $deprecatedDescription
* @param bool $isDeprecated
* @param bool $isInternal
* @param bool $isFinal
Expand All @@ -1845,6 +1849,7 @@ public function enterFunction(
array $phpDocParameterTypes,
?Type $phpDocReturnType,
?Type $throwType,
?string $deprecatedDescription,
bool $isDeprecated,
bool $isInternal,
bool $isFinal
Expand All @@ -1859,6 +1864,7 @@ public function enterFunction(
$this->getFunctionType($function->returnType, $function->returnType === null, false),
$phpDocReturnType,
$throwType,
$deprecatedDescription,
$isDeprecated,
$isInternal,
$isFinal
Expand Down
3 changes: 3 additions & 0 deletions src/Broker/Broker.php
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ public function getCustomFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope)
$phpDocParameterTags = [];
$phpDocReturnTag = null;
$phpDocThrowsTag = null;
$deprecatedTag = null;
$isDeprecated = false;
$isInternal = false;
$isFinal = false;
Expand All @@ -473,6 +474,7 @@ public function getCustomFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope)
$phpDocParameterTags = $resolvedPhpDoc->getParamTags();
$phpDocReturnTag = $resolvedPhpDoc->getReturnTag();
$phpDocThrowsTag = $resolvedPhpDoc->getThrowsTag();
$deprecatedTag = $resolvedPhpDoc->getDeprecatedTag();
$isDeprecated = $resolvedPhpDoc->isDeprecated();
$isInternal = $resolvedPhpDoc->isInternal();
$isFinal = $resolvedPhpDoc->isFinal();
Expand All @@ -485,6 +487,7 @@ public function getCustomFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope)
}, $phpDocParameterTags),
$phpDocReturnTag !== null ? $phpDocReturnTag->getType() : null,
$phpDocThrowsTag !== null ? $phpDocThrowsTag->getType() : null,
$deprecatedTag !== null ? $deprecatedTag->getMessage() : null,
$isDeprecated,
$isInternal,
$isFinal,
Expand Down
12 changes: 12 additions & 0 deletions src/PhpDoc/PhpDocNodeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace PHPStan\PhpDoc;

use PHPStan\Analyser\NameScope;
use PHPStan\PhpDoc\Tag\DeprecatedTag;
use PHPStan\PhpDoc\Tag\MethodTag;
use PHPStan\PhpDoc\Tag\MethodTagParameter;
use PHPStan\PhpDoc\Tag\ParamTag;
Expand Down Expand Up @@ -40,6 +41,7 @@ public function resolve(PhpDocNode $phpDocNode, NameScope $nameScope): ResolvedP
$this->resolveParamTags($phpDocNode, $nameScope),
$this->resolveReturnTag($phpDocNode, $nameScope),
$this->resolveThrowsTags($phpDocNode, $nameScope),
$this->resolveDeprecatedTag($phpDocNode, $nameScope),
$this->resolveIsDeprecated($phpDocNode),
$this->resolveIsInternal($phpDocNode),
$this->resolveIsFinal($phpDocNode)
Expand Down Expand Up @@ -212,6 +214,16 @@ private function resolveThrowsTags(PhpDocNode $phpDocNode, NameScope $nameScope)
return new ThrowsTag(TypeCombinator::union(...$types));
}

private function resolveDeprecatedTag(PhpDocNode $phpDocNode, NameScope $nameScope): ?\PHPStan\PhpDoc\Tag\DeprecatedTag
{
foreach ($phpDocNode->getTagsByName('@deprecated') as $tagValue) {
return new DeprecatedTag((string) $tagValue->value);
}

return null;

}

private function resolveIsDeprecated(PhpDocNode $phpDocNode): bool
{
$deprecatedTags = $phpDocNode->getTagsByName('@deprecated');
Expand Down
18 changes: 17 additions & 1 deletion src/PhpDoc/ResolvedPhpDocBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace PHPStan\PhpDoc;

use PHPStan\PhpDoc\Tag\DeprecatedTag;
use PHPStan\PhpDoc\Tag\ReturnTag;
use PHPStan\PhpDoc\Tag\ThrowsTag;

Expand All @@ -26,6 +27,9 @@ class ResolvedPhpDocBlock
/** @var \PHPStan\PhpDoc\Tag\ThrowsTag|null */
private $throwsTag;

/** @var \PHPStan\PhpDoc\Tag\DeprecatedTag|null */
private $deprecatedTag;

/** @var bool */
private $isDeprecated;

Expand All @@ -42,6 +46,7 @@ class ResolvedPhpDocBlock
* @param array<string, \PHPStan\PhpDoc\Tag\ParamTag> $paramTags
* @param \PHPStan\PhpDoc\Tag\ReturnTag|null $returnTag
* @param \PHPStan\PhpDoc\Tag\ThrowsTag|null $throwsTags
* @param \PHPStan\PhpDoc\Tag\DeprecatedTag|null $deprecatedTag
* @param bool $isDeprecated
* @param bool $isInternal
* @param bool $isFinal
Expand All @@ -53,6 +58,7 @@ private function __construct(
array $paramTags,
?ReturnTag $returnTag,
?ThrowsTag $throwsTags,
?DeprecatedTag $deprecatedTag,
bool $isDeprecated,
bool $isInternal,
bool $isFinal
Expand All @@ -64,6 +70,7 @@ private function __construct(
$this->paramTags = $paramTags;
$this->returnTag = $returnTag;
$this->throwsTag = $throwsTags;
$this->deprecatedTag = $deprecatedTag;
$this->isDeprecated = $isDeprecated;
$this->isInternal = $isInternal;
$this->isFinal = $isFinal;
Expand All @@ -76,6 +83,7 @@ private function __construct(
* @param array<string, \PHPStan\PhpDoc\Tag\ParamTag> $paramTags
* @param \PHPStan\PhpDoc\Tag\ReturnTag|null $returnTag
* @param \PHPStan\PhpDoc\Tag\ThrowsTag|null $throwsTag
* @param \PHPStan\PhpDoc\Tag\DeprecatedTag|null $deprecatedTag
* @param bool $isDeprecated
* @param bool $isInternal
* @param bool $isFinal
Expand All @@ -88,6 +96,7 @@ public static function create(
array $paramTags,
?ReturnTag $returnTag,
?ThrowsTag $throwsTag,
?DeprecatedTag $deprecatedTag,
bool $isDeprecated,
bool $isInternal,
bool $isFinal
Expand All @@ -100,6 +109,7 @@ public static function create(
$paramTags,
$returnTag,
$throwsTag,
$deprecatedTag,
$isDeprecated,
$isInternal,
$isFinal
Expand All @@ -108,7 +118,7 @@ public static function create(

public static function createEmpty(): self
{
return new self([], [], [], [], null, null, false, false, false);
return new self([], [], [], [], null, null, null, false, false, false);
}


Expand Down Expand Up @@ -154,6 +164,11 @@ public function getThrowsTag(): ?\PHPStan\PhpDoc\Tag\ThrowsTag
return $this->throwsTag;
}

public function getDeprecatedTag(): ?\PHPStan\PhpDoc\Tag\DeprecatedTag
{
return $this->deprecatedTag;
}

public function isDeprecated(): bool
{
return $this->isDeprecated;
Expand Down Expand Up @@ -182,6 +197,7 @@ public static function __set_state(array $properties): self
$properties['paramTags'],
$properties['returnTag'],
$properties['throwsTag'],
$properties['deprecatedTag'],
$properties['isDeprecated'],
$properties['isInternal'],
$properties['isFinal']
Expand Down
32 changes: 32 additions & 0 deletions src/PhpDoc/Tag/DeprecatedTag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php declare(strict_types = 1);

namespace PHPStan\PhpDoc\Tag;

class DeprecatedTag
{

/** @var string */
private $message;

public function __construct(string $message)
{
$this->message = $message;
}

public function getMessage(): string
{
return $this->message;
}

/**
* @param mixed[] $properties
* @return DeprecatedTag
*/
public static function __set_state(array $properties): self
{
return new self(
$properties['message']
);
}

}
10 changes: 10 additions & 0 deletions src/Reflection/ClassConstantReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ class ClassConstantReflection implements ConstantReflection, DeprecatableReflect
/** @var \ReflectionClassConstant */
private $reflection;

/** @var string */
private $deprecatedDescription;

/** @var bool */
private $isDeprecated;

Expand All @@ -20,12 +23,14 @@ class ClassConstantReflection implements ConstantReflection, DeprecatableReflect
public function __construct(
ClassReflection $declaringClass,
\ReflectionClassConstant $reflection,
?string $deprecatedDescription,
bool $isDeprecated,
bool $isInternal
)
{
$this->declaringClass = $declaringClass;
$this->reflection = $reflection;
$this->deprecatedDescription = $deprecatedDescription;
$this->isDeprecated = $isDeprecated;
$this->isInternal = $isInternal;
}
Expand Down Expand Up @@ -68,6 +73,11 @@ public function isDeprecated(): bool
return $this->isDeprecated;
}

public function getDeprecatedDescription(): ?string
{
return $this->deprecatedDescription;
}

public function isInternal(): bool
{
return $this->isInternal;
Expand Down
16 changes: 16 additions & 0 deletions src/Reflection/ClassReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class ClassReflection implements DeprecatableReflection, InternableReflection, F
/** @var int[]|null */
private $classHierarchyDistances;

/** @var string */
private $deprecatedDescription;

/** @var bool|null */
private $isDeprecated;

Expand Down Expand Up @@ -398,6 +401,7 @@ public function getConstant(string $name): ConstantReflection
throw new \PHPStan\Reflection\MissingConstantFromReflectionException($this->getName(), $name, $fileName !== false ? $fileName : null);
}

$deprecatedTag = null;
$isDeprecated = false;
$isInternal = false;
if ($reflectionConstant->getDocComment() !== false && $this->getFileName() !== false) {
Expand All @@ -406,13 +410,15 @@ public function getConstant(string $name): ConstantReflection
$className = $reflectionConstant->getDeclaringClass()->getName();
$resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($fileName, $className, null, $docComment);

$deprecatedDescription = $resolvedPhpDoc->getDeprecatedTag() !== null ? $resolvedPhpDoc->getDeprecatedTag()->getMessage(): null;
$isDeprecated = $resolvedPhpDoc->isDeprecated();
$isInternal = $resolvedPhpDoc->isInternal();
}

$this->constants[$name] = new ClassConstantReflection(
$this->broker->getClass($reflectionConstant->getDeclaringClass()->getName()),
$reflectionConstant,
$deprecatedTag,
$isDeprecated,
$isInternal
);
Expand Down Expand Up @@ -440,6 +446,16 @@ private function getTraitNames(): array
return $traitNames;
}

public function getDeprecatedDescription(): ?string
{
if ($this->deprecatedDescription === null) {
$resolvedPhpDoc = $this->getResolvedPhpDoc();
$this->deprecatedDescription = ($resolvedPhpDoc !== null && $resolvedPhpDoc->getDeprecatedTag()) ? $resolvedPhpDoc->getDeprecatedTag()->getMessage() : null;
}

return $this->deprecatedDescription;
}

public function isDeprecated(): bool
{
if ($this->isDeprecated === null) {
Expand Down
2 changes: 2 additions & 0 deletions src/Reflection/DeprecatableReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ interface DeprecatableReflection

public function isDeprecated(): bool;

public function getDeprecatedDescription(): ?string;

}
2 changes: 2 additions & 0 deletions src/Reflection/FunctionReflectionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface FunctionReflectionFactory
* @param \PHPStan\Type\Type[] $phpDocParameterTypes
* @param Type|null $phpDocReturnType
* @param Type|null $phpDocThrowType
* @param string|null $deprecatedDescription
* @param bool $isDeprecated
* @param bool $isInternal
* @param bool $isFinal
Expand All @@ -24,6 +25,7 @@ public function create(
array $phpDocParameterTypes,
?Type $phpDocReturnType,
?Type $phpDocThrowType,
?string $deprecatedDescription,
bool $isDeprecated,
bool $isInternal,
bool $isFinal,
Expand Down
Loading

0 comments on commit 6b325ac

Please sign in to comment.