Skip to content

Commit

Permalink
Add API for @Final attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
iluuu1994 authored and ondrejmirtes committed Jun 30, 2018
1 parent a700902 commit 8264094
Show file tree
Hide file tree
Showing 21 changed files with 307 additions and 58 deletions.
14 changes: 9 additions & 5 deletions src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -1804,15 +1804,16 @@ private function processNodesForTraitUse($node, string $traitName, Scope $classS

private function enterClassMethod(Scope $scope, Node\Stmt\ClassMethod $classMethod): Scope
{
[$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $isDeprecated, $isInternal] = $this->getPhpDocs($scope, $classMethod);
[$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $isDeprecated, $isInternal, $isFinal] = $this->getPhpDocs($scope, $classMethod);

return $scope->enterClassMethod(
$classMethod,
$phpDocParameterTypes,
$phpDocReturnType,
$phpDocThrowType,
$isDeprecated,
$isInternal
$isInternal,
$isFinal
);
}

Expand All @@ -1828,6 +1829,7 @@ private function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): arra
$phpDocThrowType = null;
$isDeprecated = false;
$isInternal = false;
$isFinal = false;
if ($functionLike->getDocComment() !== null) {
$docComment = $functionLike->getDocComment()->getText();
$file = $scope->getFile();
Expand Down Expand Up @@ -1862,22 +1864,24 @@ private function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): arra
$phpDocThrowType = $resolvedPhpDoc->getThrowsTag() !== null ? $resolvedPhpDoc->getThrowsTag()->getType() : null;
$isDeprecated = $resolvedPhpDoc->isDeprecated();
$isInternal = $resolvedPhpDoc->isInternal();
$isFinal = $resolvedPhpDoc->isFinal();
}

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

private function enterFunction(Scope $scope, Node\Stmt\Function_ $function): Scope
{
[$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $isDeprecated, $isInternal] = $this->getPhpDocs($scope, $function);
[$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $isDeprecated, $isInternal, $isFinal] = $this->getPhpDocs($scope, $function);

return $scope->enterFunction(
$function,
$phpDocParameterTypes,
$phpDocReturnType,
$phpDocThrowType,
$isDeprecated,
$isInternal
$isInternal,
$isFinal
);
}

Expand Down
14 changes: 10 additions & 4 deletions src/Analyser/Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,7 @@ public function enterTrait(ClassReflection $traitReflection): self
* @param null|Type $throwType
* @param bool $isDeprecated
* @param bool $isInternal
* @param bool $isFinal
* @return self
*/
public function enterClassMethod(
Expand All @@ -1498,7 +1499,8 @@ public function enterClassMethod(
?Type $phpDocReturnType,
?Type $throwType,
bool $isDeprecated,
bool $isInternal
bool $isInternal,
bool $isFinal
): self
{
if (!$this->isInClass()) {
Expand All @@ -1516,7 +1518,8 @@ public function enterClassMethod(
$phpDocReturnType,
$throwType,
$isDeprecated,
$isInternal
$isInternal,
$isFinal
)
);
}
Expand Down Expand Up @@ -1549,6 +1552,7 @@ private function getRealParameterTypes(Node\FunctionLike $functionLike): array
* @param null|Type $throwType
* @param bool $isDeprecated
* @param bool $isInternal
* @param bool $isFinal
* @return self
*/
public function enterFunction(
Expand All @@ -1557,7 +1561,8 @@ public function enterFunction(
?Type $phpDocReturnType,
?Type $throwType,
bool $isDeprecated,
bool $isInternal
bool $isInternal,
bool $isFinal
): self
{
return $this->enterFunctionLike(
Expand All @@ -1570,7 +1575,8 @@ public function enterFunction(
$phpDocReturnType,
$throwType,
$isDeprecated,
$isInternal
$isInternal,
$isFinal
)
);
}
Expand Down
5 changes: 4 additions & 1 deletion src/Broker/Broker.php
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ public function getCustomFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope)
$phpDocThrowsTag = null;
$isDeprecated = false;
$isInternal = false;
$isFinal = false;
if ($reflectionFunction->getFileName() !== false && $reflectionFunction->getDocComment() !== false) {
$fileName = $reflectionFunction->getFileName();
$docComment = $reflectionFunction->getDocComment();
Expand All @@ -449,6 +450,7 @@ public function getCustomFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope)
$phpDocThrowsTag = $resolvedPhpDoc->getThrowsTag();
$isDeprecated = $resolvedPhpDoc->isDeprecated();
$isInternal = $resolvedPhpDoc->isInternal();
$isFinal = $resolvedPhpDoc->isFinal();
}

$functionReflection = $this->functionReflectionFactory->create(
Expand All @@ -459,7 +461,8 @@ public function getCustomFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope)
$phpDocReturnTag !== null ? $phpDocReturnTag->getType() : null,
$phpDocThrowsTag !== null ? $phpDocThrowsTag->getType() : null,
$isDeprecated,
$isInternal
$isInternal,
$isFinal
);
$this->customFunctionReflections[$lowerCasedFunctionName] = $functionReflection;

Expand Down
10 changes: 9 additions & 1 deletion src/PhpDoc/PhpDocNodeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public function resolve(PhpDocNode $phpDocNode, NameScope $nameScope): ResolvedP
$this->resolveReturnTag($phpDocNode, $nameScope),
$this->resolveThrowsTags($phpDocNode, $nameScope),
$this->resolveIsDeprecated($phpDocNode),
$this->resolveIsInternal($phpDocNode)
$this->resolveIsInternal($phpDocNode),
$this->resolveIsFinal($phpDocNode)
);
}

Expand Down Expand Up @@ -225,4 +226,11 @@ private function resolveIsInternal(PhpDocNode $phpDocNode): bool
return count($internalTags) > 0;
}

private function resolveIsFinal(PhpDocNode $phpDocNode): bool
{
$finalTags = $phpDocNode->getTagsByName('@final');

return count($finalTags) > 0;
}

}
25 changes: 20 additions & 5 deletions src/PhpDoc/ResolvedPhpDocBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class ResolvedPhpDocBlock
/** @var bool */
private $isInternal;

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

/**
* @param array<string|int, \PHPStan\PhpDoc\Tag\VarTag> $varTags
* @param array<string, \PHPStan\PhpDoc\Tag\MethodTag> $methodTags
Expand All @@ -41,6 +44,7 @@ class ResolvedPhpDocBlock
* @param \PHPStan\PhpDoc\Tag\ThrowsTag|null $throwsTags
* @param bool $isDeprecated
* @param bool $isInternal
* @param bool $isFinal
*/
private function __construct(
array $varTags,
Expand All @@ -50,7 +54,8 @@ private function __construct(
?ReturnTag $returnTag,
?ThrowsTag $throwsTags,
bool $isDeprecated,
bool $isInternal
bool $isInternal,
bool $isFinal
)
{
$this->varTags = $varTags;
Expand All @@ -61,6 +66,7 @@ private function __construct(
$this->throwsTag = $throwsTags;
$this->isDeprecated = $isDeprecated;
$this->isInternal = $isInternal;
$this->isFinal = $isFinal;
}

/**
Expand All @@ -72,6 +78,7 @@ private function __construct(
* @param \PHPStan\PhpDoc\Tag\ThrowsTag|null $throwsTag
* @param bool $isDeprecated
* @param bool $isInternal
* @param bool $isFinal
* @return self
*/
public static function create(
Expand All @@ -82,7 +89,8 @@ public static function create(
?ReturnTag $returnTag,
?ThrowsTag $throwsTag,
bool $isDeprecated,
bool $isInternal
bool $isInternal,
bool $isFinal
): self
{
return new self(
Expand All @@ -93,13 +101,14 @@ public static function create(
$returnTag,
$throwsTag,
$isDeprecated,
$isInternal
$isInternal,
$isFinal
);
}

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


Expand Down Expand Up @@ -155,6 +164,11 @@ public function isInternal(): bool
return $this->isInternal;
}

public function isFinal(): bool
{
return $this->isFinal;
}

/**
* @param mixed[] $properties
* @return self
Expand All @@ -169,7 +183,8 @@ public static function __set_state(array $properties): self
$properties['returnTag'],
$properties['throwsTag'],
$properties['isDeprecated'],
$properties['isInternal']
$properties['isInternal'],
$properties['isFinal']
);
}

Expand Down
58 changes: 34 additions & 24 deletions src/Reflection/ClassReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

use PHPStan\Analyser\Scope;
use PHPStan\Broker\Broker;
use PHPStan\PhpDoc\ResolvedPhpDocBlock;
use PHPStan\Reflection\Php\PhpClassReflectionExtension;
use PHPStan\Reflection\Php\PhpPropertyReflection;
use PHPStan\Type\FileTypeMapper;

class ClassReflection implements DeprecatableReflection, InternableReflection
class ClassReflection implements DeprecatableReflection, InternableReflection, FinalizableReflection
{

/** @var \PHPStan\Broker\Broker */
Expand Down Expand Up @@ -50,6 +51,9 @@ class ClassReflection implements DeprecatableReflection, InternableReflection
/** @var bool|null */
private $isInternal;

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

/**
* @param Broker $broker
* @param \PHPStan\Type\FileTypeMapper $fileTypeMapper
Expand Down Expand Up @@ -418,18 +422,8 @@ private function getTraitNames(): array
public function isDeprecated(): bool
{
if ($this->isDeprecated === null) {
$fileName = $this->reflection->getFileName();
if ($fileName === false) {
return $this->isDeprecated = false;
}

$docComment = $this->reflection->getDocComment();
if ($docComment === false) {
return $this->isDeprecated = false;
}
$resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($fileName, $this->getName(), null, $docComment);

$this->isDeprecated = $resolvedPhpDoc->isDeprecated();
$resolvedPhpDoc = $this->getResolvedPhpDoc();
$this->isDeprecated = $resolvedPhpDoc !== null && $resolvedPhpDoc->isDeprecated();
}

return $this->isDeprecated;
Expand All @@ -438,21 +432,37 @@ public function isDeprecated(): bool
public function isInternal(): bool
{
if ($this->isInternal === null) {
$fileName = $this->reflection->getFileName();
if ($fileName === false) {
return $this->isInternal = false;
}
$resolvedPhpDoc = $this->getResolvedPhpDoc();
$this->isInternal = $resolvedPhpDoc !== null && $resolvedPhpDoc->isInternal();
}

$docComment = $this->reflection->getDocComment();
if ($docComment === false) {
return $this->isInternal = false;
}
$resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($fileName, $this->getName(), null, $docComment);
return $this->isInternal;
}

$this->isInternal = $resolvedPhpDoc->isInternal();
public function isFinal(): bool
{
if ($this->isFinal === null) {
$resolvedPhpDoc = $this->getResolvedPhpDoc();
$this->isFinal = $this->reflection->isFinal()
|| ($resolvedPhpDoc !== null && $resolvedPhpDoc->isFinal());
}

return $this->isInternal;
return $this->isFinal;
}

private function getResolvedPhpDoc(): ?ResolvedPhpDocBlock
{
$fileName = $this->reflection->getFileName();
if ($fileName === false) {
return null;
}

$docComment = $this->reflection->getDocComment();
if ($docComment === false) {
return null;
}

return $this->fileTypeMapper->getResolvedPhpDoc($fileName, $this->getName(), null, $docComment);
}

}
10 changes: 10 additions & 0 deletions src/Reflection/FinalizableReflection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php declare(strict_types = 1);

namespace PHPStan\Reflection;

interface FinalizableReflection
{

public function isFinal(): bool;

}
2 changes: 1 addition & 1 deletion src/Reflection/FunctionReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace PHPStan\Reflection;

interface FunctionReflection extends DeprecatableReflection, InternableReflection, ThrowableReflection
interface FunctionReflection extends DeprecatableReflection, InternableReflection, FinalizableReflection, ThrowableReflection
{

public function getName(): string;
Expand Down
4 changes: 3 additions & 1 deletion src/Reflection/FunctionReflectionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface FunctionReflectionFactory
* @param null|Type $phpDocThrowType
* @param bool $isDeprecated
* @param bool $isInternal
* @param bool $isFinal
* @return PhpFunctionReflection
*/
public function create(
Expand All @@ -23,7 +24,8 @@ public function create(
?Type $phpDocReturnType,
?Type $phpDocThrowType,
bool $isDeprecated,
bool $isInternal
bool $isInternal,
bool $isFinal
): PhpFunctionReflection;

}
5 changes: 5 additions & 0 deletions src/Reflection/Native/NativeFunctionReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,9 @@ public function isInternal(): bool
return false;
}

public function isFinal(): bool
{
return false;
}

}
Loading

0 comments on commit 8264094

Please sign in to comment.