Skip to content

Commit 80f7ff7

Browse files
committed
ConstantStringType always needs to export toPhpDocNode as ConstExprStringNode
1 parent fd05813 commit 80f7ff7

File tree

5 files changed

+49
-22
lines changed

5 files changed

+49
-22
lines changed

phpstan-baseline.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,11 @@ parameters:
10031003
count: 3
10041004
path: src/Type/Generic/TemplateConstantStringType.php
10051005

1006+
-
1007+
message: "#^Method PHPStan\\\\Type\\\\Generic\\\\TemplateConstantStringType\\:\\:toPhpDocNode\\(\\) should return PHPStan\\\\PhpDocParser\\\\Ast\\\\Type\\\\ConstTypeNode but returns PHPStan\\\\PhpDocParser\\\\Ast\\\\Type\\\\IdentifierTypeNode\\.$#"
1008+
count: 1
1009+
path: src/Type/Generic/TemplateConstantStringType.php
1010+
10061011
-
10071012
message: "#^Doing instanceof PHPStan\\\\Type\\\\IntersectionType is error\\-prone and deprecated\\.$#"
10081013
count: 3

src/Type/Constant/ConstantArrayType.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
namespace PHPStan\Type\Constant;
44

55
use PHPStan\Php\PhpVersion;
6+
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
67
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
78
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeItemNode;
89
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode;
9-
use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
10+
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
1011
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
12+
use PHPStan\PhpDocParser\Parser\StringUnescaper;
1113
use PHPStan\Reflection\ClassMemberAccessAnswerer;
1214
use PHPStan\Reflection\InaccessibleMethod;
1315
use PHPStan\Reflection\ParametersAcceptor;
@@ -58,6 +60,7 @@
5860
use function sort;
5961
use function sprintf;
6062
use function strpos;
63+
use function substr;
6164

6265
/**
6366
* @api
@@ -1558,10 +1561,16 @@ public function toPhpDocNode(): TypeNode
15581561
$items = [];
15591562
foreach ($this->keyTypes as $i => $keyType) {
15601563
$valueType = $this->valueTypes[$i];
1561-
$keyNode = $keyType->toPhpDocNode();
1562-
if ($keyNode instanceof ConstTypeNode) {
1563-
/** @var ConstExprStringNode $keyNode */
1564-
$keyNode = $keyNode->constExpr;
1564+
1565+
/** @var ConstExprStringNode|ConstExprIntegerNode $keyNode */
1566+
$keyNode = $keyType->toPhpDocNode()->constExpr;
1567+
if ($keyNode instanceof ConstExprStringNode) {
1568+
$quoteAwareString = (string) $keyNode;
1569+
$unescaped = StringUnescaper::unescapeString($quoteAwareString);
1570+
1571+
if (substr($quoteAwareString, 1, -1) === $unescaped) {
1572+
$keyNode = new IdentifierTypeNode($keyNode->value);
1573+
}
15651574
}
15661575
$items[] = new ArrayShapeItemNode(
15671576
$keyNode,

src/Type/Constant/ConstantStringType.php

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77
use PhpParser\Node\Name;
88
use PHPStan\PhpDocParser\Ast\ConstExpr\QuoteAwareConstExprStringNode;
99
use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
10-
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
1110
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
12-
use PHPStan\PhpDocParser\Parser\StringUnescaper;
1311
use PHPStan\Reflection\ClassMemberAccessAnswerer;
1412
use PHPStan\Reflection\ConstantReflection;
1513
use PHPStan\Reflection\InaccessibleMethod;
@@ -493,19 +491,11 @@ private function getObjectType(): ObjectType
493491
}
494492

495493
/**
496-
* @return ConstTypeNode|IdentifierTypeNode
494+
* @return ConstTypeNode
497495
*/
498496
public function toPhpDocNode(): TypeNode
499497
{
500-
$quoteAware = (new QuoteAwareConstExprStringNode($this->value, QuoteAwareConstExprStringNode::SINGLE_QUOTED));
501-
$quoteAwareString = (string) $quoteAware;
502-
$unescaped = StringUnescaper::unescapeString($quoteAwareString);
503-
504-
if (substr($quoteAwareString, 1, -1) === $unescaped) {
505-
return new IdentifierTypeNode($this->value);
506-
}
507-
508-
return new ConstTypeNode($quoteAware);
498+
return new ConstTypeNode(new QuoteAwareConstExprStringNode($this->value, QuoteAwareConstExprStringNode::SINGLE_QUOTED));
509499
}
510500

511501
/**

src/Type/ObjectShapeType.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
use PHPStan\Analyser\OutOfClassScope;
66
use PHPStan\Broker\Broker;
77
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
8-
use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
8+
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
99
use PHPStan\PhpDocParser\Ast\Type\ObjectShapeItemNode;
1010
use PHPStan\PhpDocParser\Ast\Type\ObjectShapeNode;
1111
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
12+
use PHPStan\PhpDocParser\Parser\StringUnescaper;
1213
use PHPStan\Reflection\ClassMemberAccessAnswerer;
1314
use PHPStan\Reflection\MissingPropertyFromReflectionException;
1415
use PHPStan\Reflection\Php\UniversalObjectCratesClassReflectionExtension;
@@ -32,6 +33,7 @@
3233
use function implode;
3334
use function in_array;
3435
use function sprintf;
36+
use function substr;
3537

3638
/** @api */
3739
class ObjectShapeType implements Type
@@ -496,10 +498,13 @@ public function toPhpDocNode(): TypeNode
496498
{
497499
$items = [];
498500
foreach ($this->properties as $name => $type) {
499-
$keyNode = (new ConstantStringType($name))->toPhpDocNode();
500-
if ($keyNode instanceof ConstTypeNode) {
501-
/** @var ConstExprStringNode $keyNode */
502-
$keyNode = $keyNode->constExpr;
501+
/** @var ConstExprStringNode $keyNode */
502+
$keyNode = (new ConstantStringType($name))->toPhpDocNode()->constExpr;
503+
$quoteAwareString = (string) $keyNode;
504+
$unescaped = StringUnescaper::unescapeString($quoteAwareString);
505+
506+
if (substr($quoteAwareString, 1, -1) === $unescaped) {
507+
$keyNode = new IdentifierTypeNode($keyNode->value);
503508
}
504509
$items[] = new ObjectShapeItemNode(
505510
$keyNode,

tests/PHPStan/Type/TypeToPhpDocNodeTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@ public function dataToPhpDocNode(): iterable
6262
'array{foo: 1, bar: 2, baz?: 3}',
6363
];
6464

65+
yield [
66+
new ConstantArrayType([
67+
new ConstantIntegerType(1),
68+
new ConstantIntegerType(2),
69+
new ConstantIntegerType(3),
70+
], [
71+
new ConstantStringType('foo'),
72+
new ConstantStringType('bar'),
73+
new ConstantStringType('baz'),
74+
], [0], [2]),
75+
'array{1: \'foo\', 2: \'bar\', 3?: \'baz\'}',
76+
];
77+
6578
yield [
6679
new ConstantIntegerType(42),
6780
'42',
@@ -82,6 +95,11 @@ public function dataToPhpDocNode(): iterable
8295
'false',
8396
];
8497

98+
yield [
99+
new ConstantStringType('foo'),
100+
"'foo'",
101+
];
102+
85103
yield [
86104
new GenericClassStringType(new ObjectType('stdClass')),
87105
'class-string<stdClass>',

0 commit comments

Comments
 (0)