Last active
May 7, 2023 15:38
-
-
Save ellisgl/7badc78672abb83c1568205368d5c55d to your computer and use it in GitHub Desktop.
Use PHPStan\PhpDocParser to parse the return types listed in a PHPDoc comment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
include 'vendor/autoload.php'; | |
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; | |
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode; | |
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode; | |
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; | |
use PHPStan\PhpDocParser\Ast\Type\IntersectionTypeNode; | |
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode; | |
use PHPStan\PhpDocParser\Lexer\Lexer; | |
use PHPStan\PhpDocParser\Parser\ConstExprParser; | |
use PHPStan\PhpDocParser\Parser\PhpDocParser; | |
use PHPStan\PhpDocParser\Parser\TokenIterator; | |
use PHPStan\PhpDocParser\Parser\TypeParser; | |
// Test PHPDocs | |
$docComment = '/** | |
* @return Collection&int[] | |
*/'; | |
$docComment2 = '/** | |
* @return string|int[]|null | |
*/'; | |
$docComment3 = '/** | |
* @return string | |
*/'; | |
$docComment3 = '/** | |
* @return int[] | |
*/'; | |
// Construct required objects for the PhpDocParser construct. | |
$lexer = new Lexer(); | |
$typeParser = new TypeParser(); | |
$constExprParser = new ConstExprParser(); | |
// Set the required options. | |
$requireWhitespaceBeforeDescription = true; | |
$preserveTypeAliasesWithInvalidTypes = true; | |
// Only parse return tags from PHPDoc. | |
$usedAttributes = ['@return']; | |
// Create the parser. | |
$phpDocParser = new PhpDocParser( | |
$typeParser, | |
$constExprParser, | |
$requireWhitespaceBeforeDescription, | |
$preserveTypeAliasesWithInvalidTypes, | |
$usedAttributes | |
); | |
// Create the tokens from the doc comment. | |
$tokens = $lexer->tokenize($docComment3); | |
// Parse the tokens into a PhpDocNode object. | |
$phpDocNode = $phpDocParser->parse(new TokenIterator($tokens)); | |
// var_dump($phpDocNode); | |
// Storage for the return types. | |
$returnTypes = []; | |
// Loop through the children of the PhpDocNode object. | |
foreach ($phpDocNode->children as $child) { | |
// Check if the child is a PhpDocTagNode. | |
if ($child instanceof PhpDocTagNode) { | |
$value = $child->value; | |
// print_r($value); | |
// Check if the child is a ReturnTagValueNode. | |
if ($value instanceof ReturnTagValueNode) { | |
// Are we dealing with an intersection type return? | |
if ($value->type instanceof IntersectionTypeNode) { | |
// Store the types in an array, which will be returned as an array inside $returnTypes. | |
$types = []; | |
foreach ($value->type->types as $type) { | |
if ($type instanceof IdentifierTypeNode) { | |
// Simple type, store it in the array. | |
$types[] = $type->name; | |
} elseif ($type instanceof ArrayTypeNode && $type->type instanceof IdentifierTypeNode) { | |
// Array type, store it in the array as shown in the string. | |
$types[] = $type->type->name . '[]'; | |
} | |
} | |
// Store the array in $returnTypes. | |
$returnTypes[] = $types; | |
} elseif ($value->type instanceof UnionTypeNode) { | |
// This is of a union type. | |
// Loop through the types in the union. | |
foreach ($value->type->types as $type) { | |
if ($type instanceof IdentifierTypeNode) { | |
// Simple type, store it in the array. | |
$returnTypes[] = $type->name; | |
} elseif ($type instanceof ArrayTypeNode && $type->type instanceof IdentifierTypeNode) { | |
// Array type, store it in the array as shown in the string. | |
$returnTypes[] = $type->type->name . '[]'; | |
} | |
} | |
} elseif ($value->type instanceof IdentifierTypeNode) { | |
$returnTypes[] = $value->type->name; | |
} elseif ($value->type instanceof ArrayTypeNode && $value->type->type instanceof IdentifierTypeNode) { | |
/** @var IdentifierTypeNode $type */ | |
$type = $value->type->type; | |
$returnTypes[] = $type->name . '[]'; | |
} | |
} | |
} | |
} | |
print_r($returnTypes); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment