Skip to content

Commit

Permalink
ConstantStringType always needs to export toPhpDocNode as ConstExprSt…
Browse files Browse the repository at this point in the history
…ringNode
  • Loading branch information
ondrejmirtes committed Apr 18, 2023
1 parent fd05813 commit 80f7ff7
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 22 deletions.
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,11 @@ parameters:
count: 3
path: src/Type/Generic/TemplateConstantStringType.php

-
message: "#^Method PHPStan\\\\Type\\\\Generic\\\\TemplateConstantStringType\\:\\:toPhpDocNode\\(\\) should return PHPStan\\\\PhpDocParser\\\\Ast\\\\Type\\\\ConstTypeNode but returns PHPStan\\\\PhpDocParser\\\\Ast\\\\Type\\\\IdentifierTypeNode\\.$#"
count: 1
path: src/Type/Generic/TemplateConstantStringType.php

-
message: "#^Doing instanceof PHPStan\\\\Type\\\\IntersectionType is error\\-prone and deprecated\\.$#"
count: 3
Expand Down
19 changes: 14 additions & 5 deletions src/Type/Constant/ConstantArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
namespace PHPStan\Type\Constant;

use PHPStan\Php\PhpVersion;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeItemNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode;
use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\PhpDocParser\Parser\StringUnescaper;
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Reflection\InaccessibleMethod;
use PHPStan\Reflection\ParametersAcceptor;
Expand Down Expand Up @@ -58,6 +60,7 @@
use function sort;
use function sprintf;
use function strpos;
use function substr;

/**
* @api
Expand Down Expand Up @@ -1558,10 +1561,16 @@ public function toPhpDocNode(): TypeNode
$items = [];
foreach ($this->keyTypes as $i => $keyType) {
$valueType = $this->valueTypes[$i];
$keyNode = $keyType->toPhpDocNode();
if ($keyNode instanceof ConstTypeNode) {
/** @var ConstExprStringNode $keyNode */
$keyNode = $keyNode->constExpr;

/** @var ConstExprStringNode|ConstExprIntegerNode $keyNode */
$keyNode = $keyType->toPhpDocNode()->constExpr;
if ($keyNode instanceof ConstExprStringNode) {
$quoteAwareString = (string) $keyNode;
$unescaped = StringUnescaper::unescapeString($quoteAwareString);

if (substr($quoteAwareString, 1, -1) === $unescaped) {
$keyNode = new IdentifierTypeNode($keyNode->value);
}
}
$items[] = new ArrayShapeItemNode(
$keyNode,
Expand Down
14 changes: 2 additions & 12 deletions src/Type/Constant/ConstantStringType.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
use PhpParser\Node\Name;
use PHPStan\PhpDocParser\Ast\ConstExpr\QuoteAwareConstExprStringNode;
use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\PhpDocParser\Parser\StringUnescaper;
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Reflection\ConstantReflection;
use PHPStan\Reflection\InaccessibleMethod;
Expand Down Expand Up @@ -493,19 +491,11 @@ private function getObjectType(): ObjectType
}

/**
* @return ConstTypeNode|IdentifierTypeNode
* @return ConstTypeNode
*/
public function toPhpDocNode(): TypeNode
{
$quoteAware = (new QuoteAwareConstExprStringNode($this->value, QuoteAwareConstExprStringNode::SINGLE_QUOTED));
$quoteAwareString = (string) $quoteAware;
$unescaped = StringUnescaper::unescapeString($quoteAwareString);

if (substr($quoteAwareString, 1, -1) === $unescaped) {
return new IdentifierTypeNode($this->value);
}

return new ConstTypeNode($quoteAware);
return new ConstTypeNode(new QuoteAwareConstExprStringNode($this->value, QuoteAwareConstExprStringNode::SINGLE_QUOTED));
}

/**
Expand Down
15 changes: 10 additions & 5 deletions src/Type/ObjectShapeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
use PHPStan\Analyser\OutOfClassScope;
use PHPStan\Broker\Broker;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\ObjectShapeItemNode;
use PHPStan\PhpDocParser\Ast\Type\ObjectShapeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\PhpDocParser\Parser\StringUnescaper;
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Reflection\MissingPropertyFromReflectionException;
use PHPStan\Reflection\Php\UniversalObjectCratesClassReflectionExtension;
Expand All @@ -32,6 +33,7 @@
use function implode;
use function in_array;
use function sprintf;
use function substr;

/** @api */
class ObjectShapeType implements Type
Expand Down Expand Up @@ -496,10 +498,13 @@ public function toPhpDocNode(): TypeNode
{
$items = [];
foreach ($this->properties as $name => $type) {
$keyNode = (new ConstantStringType($name))->toPhpDocNode();
if ($keyNode instanceof ConstTypeNode) {
/** @var ConstExprStringNode $keyNode */
$keyNode = $keyNode->constExpr;
/** @var ConstExprStringNode $keyNode */
$keyNode = (new ConstantStringType($name))->toPhpDocNode()->constExpr;
$quoteAwareString = (string) $keyNode;
$unescaped = StringUnescaper::unescapeString($quoteAwareString);

if (substr($quoteAwareString, 1, -1) === $unescaped) {
$keyNode = new IdentifierTypeNode($keyNode->value);
}
$items[] = new ObjectShapeItemNode(
$keyNode,
Expand Down
18 changes: 18 additions & 0 deletions tests/PHPStan/Type/TypeToPhpDocNodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ public function dataToPhpDocNode(): iterable
'array{foo: 1, bar: 2, baz?: 3}',
];

yield [
new ConstantArrayType([
new ConstantIntegerType(1),
new ConstantIntegerType(2),
new ConstantIntegerType(3),
], [
new ConstantStringType('foo'),
new ConstantStringType('bar'),
new ConstantStringType('baz'),
], [0], [2]),
'array{1: \'foo\', 2: \'bar\', 3?: \'baz\'}',
];

yield [
new ConstantIntegerType(42),
'42',
Expand All @@ -82,6 +95,11 @@ public function dataToPhpDocNode(): iterable
'false',
];

yield [
new ConstantStringType('foo'),
"'foo'",
];

yield [
new GenericClassStringType(new ObjectType('stdClass')),
'class-string<stdClass>',
Expand Down

0 comments on commit 80f7ff7

Please sign in to comment.