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