1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Reflection;
4:
5: use PhpParser\Node\Expr;
6: use PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode;
7: use PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant;
8: use PHPStan\TrinaryLogic;
9: use PHPStan\Type\Type;
10: use PHPStan\Type\TypehintHelper;
11: use const NAN;
12:
13: /** @api */
14: class ClassConstantReflection implements ConstantReflection
15: {
16:
17: private ?Type $valueType = null;
18:
19: public function __construct(
20: private InitializerExprTypeResolver $initializerExprTypeResolver,
21: private ClassReflection $declaringClass,
22: private ReflectionClassConstant $reflection,
23: private ?Type $nativeType,
24: private ?Type $phpDocType,
25: private ?string $deprecatedDescription,
26: private bool $isDeprecated,
27: private bool $isInternal,
28: )
29: {
30: }
31:
32: public function getName(): string
33: {
34: return $this->reflection->getName();
35: }
36:
37: public function getFileName(): ?string
38: {
39: return $this->declaringClass->getFileName();
40: }
41:
42: /**
43: * @deprecated Use getValueExpr()
44: * @return mixed
45: */
46: public function getValue()
47: {
48: try {
49: return $this->reflection->getValue();
50: } catch (UnableToCompileNode) {
51: return NAN;
52: }
53: }
54:
55: public function getValueExpr(): Expr
56: {
57: return $this->reflection->getValueExpression();
58: }
59:
60: public function hasPhpDocType(): bool
61: {
62: return $this->phpDocType !== null;
63: }
64:
65: public function getPhpDocType(): ?Type
66: {
67: return $this->phpDocType;
68: }
69:
70: public function hasNativeType(): bool
71: {
72: return $this->nativeType !== null;
73: }
74:
75: public function getNativeType(): ?Type
76: {
77: return $this->nativeType;
78: }
79:
80: public function getValueType(): Type
81: {
82: if ($this->valueType === null) {
83: if ($this->phpDocType !== null) {
84: if ($this->nativeType !== null) {
85: return $this->valueType = TypehintHelper::decideType(
86: $this->nativeType,
87: $this->phpDocType,
88: );
89: }
90:
91: return $this->phpDocType;
92: } elseif ($this->nativeType !== null) {
93: return $this->nativeType;
94: }
95:
96: $this->valueType = $this->initializerExprTypeResolver->getType($this->getValueExpr(), InitializerExprContext::fromClassReflection($this->declaringClass));
97: }
98:
99: return $this->valueType;
100: }
101:
102: public function getDeclaringClass(): ClassReflection
103: {
104: return $this->declaringClass;
105: }
106:
107: public function isStatic(): bool
108: {
109: return true;
110: }
111:
112: public function isPrivate(): bool
113: {
114: return $this->reflection->isPrivate();
115: }
116:
117: public function isPublic(): bool
118: {
119: return $this->reflection->isPublic();
120: }
121:
122: public function isFinal(): bool
123: {
124: return $this->reflection->isFinal();
125: }
126:
127: public function isDeprecated(): TrinaryLogic
128: {
129: return TrinaryLogic::createFromBoolean($this->isDeprecated);
130: }
131:
132: public function getDeprecatedDescription(): ?string
133: {
134: if ($this->isDeprecated) {
135: return $this->deprecatedDescription;
136: }
137:
138: return null;
139: }
140:
141: public function isInternal(): TrinaryLogic
142: {
143: return TrinaryLogic::createFromBoolean($this->isInternal);
144: }
145:
146: public function getDocComment(): ?string
147: {
148: $docComment = $this->reflection->getDocComment();
149: if ($docComment === false) {
150: return null;
151: }
152:
153: return $docComment;
154: }
155:
156: }
157: