class AnnotationHelper
Same name in this branch
- 11.1.x vendor/phpstan/phpstan-phpunit/src/Rules/PHPUnit/AnnotationHelper.php \PHPStan\Rules\PHPUnit\AnnotationHelper
@internal
Hierarchy
- class \SlevomatCodingStandard\Helpers\AnnotationHelper
Expanded class hierarchy of AnnotationHelper
19 files declare their use of AnnotationHelper
- AnnotationNameSniff.php in vendor/
slevomat/ coding-standard/ SlevomatCodingStandard/ Sniffs/ Commenting/ AnnotationNameSniff.php - DeprecatedAnnotationDeclarationSniff.php in vendor/
slevomat/ coding-standard/ SlevomatCodingStandard/ Sniffs/ Commenting/ DeprecatedAnnotationDeclarationSniff.php - DisallowArrayTypeHintSyntaxSniff.php in vendor/
slevomat/ coding-standard/ SlevomatCodingStandard/ Sniffs/ TypeHints/ DisallowArrayTypeHintSyntaxSniff.php - DisallowMixedTypeHintSniff.php in vendor/
slevomat/ coding-standard/ SlevomatCodingStandard/ Sniffs/ TypeHints/ DisallowMixedTypeHintSniff.php - DocCommentSpacingSniff.php in vendor/
slevomat/ coding-standard/ SlevomatCodingStandard/ Sniffs/ Commenting/ DocCommentSpacingSniff.php
File
-
vendor/
slevomat/ coding-standard/ SlevomatCodingStandard/ Helpers/ AnnotationHelper.php, line 35
Namespace
SlevomatCodingStandard\HelpersView source
class AnnotationHelper {
public const STATIC_ANALYSIS_PREFIXES = [
'psalm',
'phpstan',
];
/**
* @return list<Annotation>
*/
public static function getAnnotations(File $phpcsFile, int $pointer, ?string $name = null) : array {
$docCommentOpenPointer = DocCommentHelper::findDocCommentOpenPointer($phpcsFile, $pointer);
if ($docCommentOpenPointer === null) {
return [];
}
return SniffLocalCache::getAndSetIfNotCached($phpcsFile, sprintf('annotations-%d-%s', $docCommentOpenPointer, $name ?? 'all'), static function () use ($phpcsFile, $docCommentOpenPointer, $name) : array {
$annotations = [];
if ($name !== null) {
foreach (self::getAnnotations($phpcsFile, $docCommentOpenPointer) as $annotation) {
if ($annotation->getName() === $name) {
$annotations[] = $annotation;
}
}
}
else {
$parsedDocComment = DocCommentHelper::parseDocComment($phpcsFile, $docCommentOpenPointer);
if ($parsedDocComment !== null) {
foreach ($parsedDocComment->getNode()
->getTags() as $node) {
$annotationStartPointer = $parsedDocComment->getNodeStartPointer($phpcsFile, $node);
$annotations[] = new Annotation($node, $annotationStartPointer, $parsedDocComment->getNodeEndPointer($phpcsFile, $node, $annotationStartPointer));
}
}
}
return $annotations;
});
}
/**
* @param class-string $type
* @return list<Node>
*/
public static function getAnnotationNodesByType(Node $node, string $type) : array {
static $visitor;
static $traverser;
if ($visitor === null) {
$visitor = new class extends AbstractNodeVisitor {
/** @var class-string */
private $type;
/** @var list<Node> */
private $nodes = [];
/** @var list<Node> */
private $nodesToIgnore = [];
/**
* @return Node|list<Node>|NodeTraverser::*|null
*/
public function enterNode(Node $node) {
if ($this->type === IdentifierTypeNode::class) {
if ($node instanceof ArrayShapeItemNode || $node instanceof ObjectShapeItemNode) {
$this->nodesToIgnore[] = $node->keyName;
}
elseif ($node instanceof DoctrineArgument) {
$this->nodesToIgnore[] = $node->key;
}
}
if ($node instanceof $this->type && !in_array($node, $this->nodesToIgnore, true)) {
$this->nodes[] = $node;
}
return null;
}
/**
* @param class-string $type
*/
public function setType(string $type) : void {
$this->type = $type;
}
public function clean() : void {
$this->nodes = [];
$this->nodesToIgnore = [];
}
/**
* @return list<Node>
*/
public function getNodes() : array {
return $this->nodes;
}
};
}
if ($traverser === null) {
$traverser = new NodeTraverser([
$visitor,
]);
}
$visitor->setType($type);
$visitor->clean();
$traverser->traverse([
$node,
]);
return $visitor->getNodes();
}
public static function fixAnnotation(ParsedDocComment $parsedDocComment, Annotation $annotation, Node $nodeToFix, Node $fixedNode) : string {
$originalNode = $annotation->getNode();
/** @var PhpDocNode $newPhpDocNode */
$newPhpDocNode = PhpDocParserHelper::cloneNode($parsedDocComment->getNode());
foreach ($newPhpDocNode->getTags() as $node) {
if ($node->getAttribute(Attribute::ORIGINAL_NODE) === $originalNode) {
self::changeAnnotationNode($node, $nodeToFix, $fixedNode);
break;
}
}
return PhpDocParserHelper::getPrinter()->printFormatPreserving($newPhpDocNode, $parsedDocComment->getNode(), $parsedDocComment->getTokens());
}
/**
* @param array<int, string> $traversableTypeHints
*/
public static function isAnnotationUseless(File $phpcsFile, int $functionPointer, ?TypeHint $typeHint, Annotation $annotation, array $traversableTypeHints, bool $enableUnionTypeHint = false, bool $enableIntersectionTypeHint = false, bool $enableStandaloneNullTrueFalseTypeHints = false) : bool {
if ($annotation->isInvalid()) {
return false;
}
if ($typeHint === null) {
return false;
}
/** @var ParamTagValueNode|TypelessParamTagValueNode|ReturnTagValueNode|VarTagValueNode $annotationValue */
$annotationValue = $annotation->getValue();
if ($annotationValue->description !== '') {
return false;
}
if ($annotationValue instanceof TypelessParamTagValueNode) {
return true;
}
$annotationType = $annotationValue->type;
if (TypeHintHelper::isTraversableType(TypeHintHelper::getFullyQualifiedTypeHint($phpcsFile, $functionPointer, $typeHint->getTypeHintWithoutNullabilitySymbol()), $traversableTypeHints) && !($annotationType instanceof IdentifierTypeNode && TypeHintHelper::isSimpleIterableTypeHint(strtolower($annotationType->name)))) {
return false;
}
if (AnnotationTypeHelper::containsStaticOrThisType($annotationType)) {
return false;
}
if (AnnotationTypeHelper::containsJustTwoTypes($annotationType) || $enableUnionTypeHint && ($annotationType instanceof UnionTypeNode || $annotationType instanceof IdentifierTypeNode && TypeHintHelper::isUnofficialUnionTypeHint($annotationType->name)) || $enableIntersectionTypeHint && $annotationType instanceof IntersectionTypeNode) {
$annotationTypeHint = AnnotationTypeHelper::print($annotationType);
return TypeHintHelper::typeHintEqualsAnnotation($phpcsFile, $functionPointer, $typeHint->getTypeHint(), $annotationTypeHint);
}
if ($annotationType instanceof ObjectShapeNode) {
return false;
}
if ($annotationType instanceof ConstTypeNode) {
return false;
}
if ($annotationType instanceof GenericTypeNode) {
return false;
}
if ($annotationType instanceof CallableTypeNode) {
return false;
}
if ($annotationType instanceof ConditionalTypeNode) {
return false;
}
if ($annotationType instanceof ConditionalTypeForParameterNode) {
return false;
}
if ($annotationType instanceof IdentifierTypeNode) {
if (in_array(strtolower($annotationType->name), [
'true',
'false',
'null',
], true)) {
return $enableStandaloneNullTrueFalseTypeHints;
}
if (in_array(strtolower($annotationType->name), [
'class-string',
'trait-string',
'callable-string',
'numeric-string',
'non-empty-string',
'non-falsy-string',
'literal-string',
'positive-int',
'negative-int',
], true)) {
return false;
}
}
$annotationTypeHint = AnnotationTypeHelper::getTypeHintFromOneType($annotationType);
return TypeHintHelper::typeHintEqualsAnnotation($phpcsFile, $functionPointer, $typeHint->getTypeHintWithoutNullabilitySymbol(), $annotationTypeHint);
}
private static function changeAnnotationNode(PhpDocTagNode $tagNode, Node $nodeToChange, Node $changedNode) : PhpDocTagNode {
static $visitor;
static $traverser;
if ($visitor === null) {
$visitor = new class extends AbstractNodeVisitor {
/** @var Node */
private $nodeToChange;
/** @var Node */
private $changedNode;
/**
* @return Node|list<Node>|NodeTraverser::*|null
*/
public function enterNode(Node $node) {
if ($node->getAttribute(Attribute::ORIGINAL_NODE) === $this->nodeToChange) {
return $this->changedNode;
}
return null;
}
public function setNodeToChange(Node $nodeToChange) : void {
$this->nodeToChange = $nodeToChange;
}
public function setChangedNode(Node $changedNode) : void {
$this->changedNode = $changedNode;
}
};
}
if ($traverser === null) {
$traverser = new NodeTraverser([
$visitor,
]);
}
$visitor->setNodeToChange($nodeToChange);
$visitor->setChangedNode($changedNode);
[
$changedTagNode,
] = $traverser->traverse([
$tagNode,
]);
return $changedTagNode;
}
}
Members
Title Sort descending | Modifiers | Object type | Summary |
---|---|---|---|
AnnotationHelper::changeAnnotationNode | private static | function | |
AnnotationHelper::fixAnnotation | public static | function | |
AnnotationHelper::getAnnotationNodesByType | public static | function | * |
AnnotationHelper::getAnnotations | public static | function | * |
AnnotationHelper::isAnnotationUseless | public static | function | * |
AnnotationHelper::STATIC_ANALYSIS_PREFIXES | public | constant |