project_start/phpstorm-stubs/tests/Model/PHPConst.php

148 lines
4.6 KiB
PHP

<?php
namespace StubTests\Model;
use Exception;
use PhpParser\Node\Const_;
use PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\UnaryMinus;
use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\Enum_;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\NodeAbstract;
use ReflectionClassConstant;
use stdClass;
use function in_array;
class PHPConst extends BasePHPElement
{
/**
* @var string|null
*/
public $parentName;
/**
* @var bool|int|string|float|null
*/
public $value;
/**
* @var string|null
*/
public $visibility;
/**
* @param ReflectionClassConstant $reflectionObject
* @return static
*/
public function readObjectFromReflection($reflectionObject)
{
$this->name = $reflectionObject->name;
$this->value = $reflectionObject->getValue();
if ($reflectionObject->isPrivate()) {
$this->visibility = 'private';
} elseif ($reflectionObject->isProtected()) {
$this->visibility = 'protected';
} else {
$this->visibility = 'public';
}
return $this;
}
/**
* @param Const_ $node
* @return static
*/
public function readObjectFromStubNode($node)
{
$this->name = $this->getConstantFQN($node, $node->name->name);
$this->value = $this->getConstValue($node);
$this->collectTags($node);
$parentNode = $node->getAttribute('parent');
if (property_exists($parentNode, 'attrGroups')) {
$this->availableVersionsRangeFromAttribute = self::findAvailableVersionsRangeFromAttribute($parentNode->attrGroups);
}
if ($parentNode instanceof ClassConst) {
if ($parentNode->isPrivate()) {
$this->visibility = 'private';
} elseif ($parentNode->isProtected()) {
$this->visibility = 'protected';
} else {
$this->visibility = 'public';
}
$this->parentName = self::getFQN($parentNode->getAttribute('parent'));
}
return $this;
}
/**
* @param $node
* @return int|string|bool|float|null
*/
protected function getConstValue($node)
{
if (in_array('value', $node->value->getSubNodeNames(), true)) {
return $node->value->value;
}
if (in_array('expr', $node->value->getSubNodeNames(), true)) {
if ($node->value instanceof UnaryMinus) {
return -$node->value->expr->value;
} elseif ($node->value instanceof Cast && $node->value->expr instanceof ConstFetch) {
return $node->value->expr->name->name;
}
return $node->value->expr->value;
}
if (in_array('name', $node->value->getSubNodeNames(), true)) {
$value = isset($node->value->name->parts[0]) ? $node->value->name->parts[0] : $node->value->name->name;
return $value === 'null' ? null : $value;
}
return null;
}
/**
* @param NodeAbstract $node
* @param string $nodeName
* @return string
*/
protected function getConstantFQN(NodeAbstract $node, $nodeName)
{
$namespace = '';
$parentNode = $node->getAttribute('parent');
if ($parentNode instanceof Enum_) {
return $nodeName;
} else {
$parentParentNode = $parentNode->getAttribute('parent');
if ($parentParentNode instanceof Namespace_ && !empty($parentParentNode->name)) {
$namespace = '\\' . $parentParentNode->name->name . '\\';
}
}
return $namespace . $nodeName;
}
/**
* @param stdClass|array $jsonData
* @throws Exception
*/
public function readMutedProblems($jsonData)
{
foreach ($jsonData as $constant) {
if ($constant->name === $this->name && !empty($constant->problems)) {
foreach ($constant->problems as $problem) {
switch ($problem->description) {
case 'wrong value':
$this->mutedProblems[StubProblemType::WRONG_CONSTANT_VALUE] = $problem->versions;
break;
case 'missing constant':
$this->mutedProblems[StubProblemType::STUB_IS_MISSED] = $problem->versions;
break;
default:
throw new Exception("Unexpected value $problem->description");
}
}
}
}
}
}