Skip to content

Commit 59e7788

Browse files
committed
Fix false positive abount allowed constants in parameters
1 parent 57d052c commit 59e7788

12 files changed

+75
-16
lines changed

src/Reflection/BetterReflection/BetterReflectionProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ public function getConstant(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAn
444444
array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute) => ReflectionAttributeFactory::create($betterReflectionAttribute), $constantReflection->getAttributes()),
445445
InitializerExprContext::fromGlobalConstant($constantReflection),
446446
),
447+
$constantReflection->isInternal(),
447448
);
448449
}
449450

src/Reflection/Constant/RuntimeConstantReflection.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public function __construct(
2020
private TrinaryLogic $isDeprecated,
2121
private ?string $deprecatedDescription,
2222
private array $attributes,
23+
private bool $internal,
2324
)
2425
{
2526
}
@@ -29,6 +30,16 @@ public function getName(): string
2930
return $this->name;
3031
}
3132

33+
public function describe(): string
34+
{
35+
return $this->name;
36+
}
37+
38+
public function isBuiltin(): TrinaryLogic
39+
{
40+
return TrinaryLogic::createFromBoolean($this->internal);
41+
}
42+
3243
public function getValueType(): Type
3344
{
3445
return $this->valueType;

src/Reflection/ConstantReflection.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ interface ConstantReflection
2020

2121
public function getName(): string;
2222

23+
public function describe(): string;
24+
25+
public function isBuiltin(): TrinaryLogic;
26+
2327
public function getValueType(): Type;
2428

2529
public function isDeprecated(): TrinaryLogic;

src/Reflection/Dummy/DummyClassConstantReflection.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PHPStan\Type\MixedType;
1313
use PHPStan\Type\Type;
1414
use stdClass;
15+
use function sprintf;
1516

1617
final class DummyClassConstantReflection implements ClassConstantReflection
1718
{
@@ -62,6 +63,16 @@ public function getName(): string
6263
return $this->name;
6364
}
6465

66+
public function describe(): string
67+
{
68+
return sprintf('%s::%s', $this->getDeclaringClass()->getDisplayName(), $this->name);
69+
}
70+
71+
public function isBuiltin(): TrinaryLogic
72+
{
73+
return TrinaryLogic::createFromBoolean($this->getDeclaringClass()->isBuiltin());
74+
}
75+
6576
public function getValueType(): Type
6677
{
6778
return new MixedType();

src/Reflection/ParameterAllowedConstants.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ public function getExclusiveGroups(): array
4747
return $this->exclusiveGroups;
4848
}
4949

50-
private function resolveConstantName(ConstantReflection $constant): string
51-
{
52-
if ($constant instanceof ClassConstantReflection) {
53-
return $constant->getDeclaringClass()->getName() . '::' . $constant->getName();
54-
}
55-
56-
return $constant->getName();
57-
}
58-
5950
/**
6051
* @param list<ConstantReflection> $constants
6152
*/
@@ -67,7 +58,11 @@ public function check(array $constants): AllowedConstantsResult
6758
$names = [];
6859

6960
foreach ($constants as $constant) {
70-
$name = $this->resolveConstantName($constant);
61+
if ($constant->isBuiltin()->no()) {
62+
continue;
63+
}
64+
65+
$name = $constant->describe();
7166
$names[] = $name;
7267

7368
if (in_array($name, $this->constants, true)) {

src/Reflection/RealClassClassConstantReflection.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPStan\TrinaryLogic;
1010
use PHPStan\Type\Type;
1111
use PHPStan\Type\TypehintHelper;
12+
use function sprintf;
1213

1314
final class RealClassClassConstantReflection implements ClassConstantReflection
1415
{
@@ -39,6 +40,16 @@ public function getName(): string
3940
return $this->reflection->getName();
4041
}
4142

43+
public function describe(): string
44+
{
45+
return sprintf('%s::%s', $this->declaringClass->getDisplayName(), $this->getName());
46+
}
47+
48+
public function isBuiltin(): TrinaryLogic
49+
{
50+
return TrinaryLogic::createFromBoolean($this->declaringClass->isBuiltin());
51+
}
52+
4253
public function getFileName(): ?string
4354
{
4455
return $this->declaringClass->getFileName();

src/Rules/FunctionCallParametersCheck.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ public function check(
424424
foreach ($result->getDisallowedConstants() as $disallowedConstant) {
425425
$errors[] = RuleErrorBuilder::message(sprintf(
426426
$invalidConstantMessage,
427-
$disallowedConstant->getName(),
427+
$disallowedConstant->describe(),
428428
lcfirst($this->describeParameter($parameter, $argumentName ?? $i + 1)),
429429
))
430430
->identifier('argument.invalidConstant')

src/Rules/RestrictedUsage/RewrittenDeclaringClassClassConstantReflection.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use PHPStan\Reflection\ClassReflection;
99
use PHPStan\TrinaryLogic;
1010
use PHPStan\Type\Type;
11+
use function sprintf;
1112

1213
final class RewrittenDeclaringClassClassConstantReflection implements ClassConstantReflection
1314
{
@@ -89,6 +90,16 @@ public function getName(): string
8990
return $this->constantReflection->getName();
9091
}
9192

93+
public function describe(): string
94+
{
95+
return sprintf('%s::%s', $this->getDeclaringClass()->getDisplayName(), $this->getName());
96+
}
97+
98+
public function isBuiltin(): TrinaryLogic
99+
{
100+
return TrinaryLogic::createFromBoolean($this->getDeclaringClass()->isBuiltin());
101+
}
102+
92103
public function getValueType(): Type
93104
{
94105
return $this->constantReflection->getValueType();

tests/PHPStan/Rules/Classes/InstantiationRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ public function testConstantParameterCheckInstantiation(): void
624624
12,
625625
],
626626
[
627-
'Constant GREGORIAN is not allowed for parameter #2 $dateType of class IntlDateFormatter constructor.',
627+
'Constant IntlDateFormatter::GREGORIAN is not allowed for parameter #2 $dateType of class IntlDateFormatter constructor.',
628628
18,
629629
],
630630
]);

tests/PHPStan/Rules/Functions/data/constant-parameter-check.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,18 @@
8080

8181
// round: single-value parameter - correct
8282
round(1.5, 0, PHP_ROUND_HALF_UP);
83+
84+
class Foo
85+
{
86+
private const PASSWORD_ALGORITHM = PASSWORD_ARGON2ID;
87+
88+
// user-defined class constant wrapping a valid constant - should not report
89+
public function hashPassword(string $password): string
90+
{
91+
return password_hash($password, self::PASSWORD_ALGORITHM);
92+
}
93+
}
94+
95+
// user-defined global constant wrapping a valid constant - should not report
96+
define('MY_JSON_FLAGS', JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
97+
json_encode([], MY_JSON_FLAGS);

0 commit comments

Comments
 (0)