Skip to content

Commit 9e7f39e

Browse files
committed
[BCB] ClassPropertyNode::getNativeType() return type changed from AST node to Type
1 parent 5eacc66 commit 9e7f39e

7 files changed

+51
-48
lines changed

UPGRADING.md

+1
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,4 @@ Instead of `PHPStanTestCase::createBroker()`, call `PHPStanTestCase::createRefle
299299
* Added more methods around PHPDoc types and native types to the (new) `ClassConstantReflection`
300300
* Interface `GlobalConstantReflection` renamed to `ConstantReflection`
301301
* Renamed interfaces and classes from `*WithPhpDocs` to `Extended*`
302+
* `ClassPropertyNode::getNativeType()` return type changed from AST node to `Type|null

src/Analyser/NodeScopeResolver.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@
170170
use PHPStan\Type\NullType;
171171
use PHPStan\Type\ObjectType;
172172
use PHPStan\Type\ObjectWithoutClassType;
173+
use PHPStan\Type\ParserNodeTypeToPHPStanType;
173174
use PHPStan\Type\ResourceType;
174175
use PHPStan\Type\StaticType;
175176
use PHPStan\Type\StaticTypeFactory;
@@ -648,7 +649,7 @@ private function processStmtNode(
648649
$nodeCallback(new ClassPropertyNode(
649650
$param->var->name,
650651
$param->flags,
651-
$param->type,
652+
$param->type !== null ? ParserNodeTypeToPHPStanType::resolve($param->type, $scope->getClassReflection()) : null,
652653
null,
653654
$phpDoc,
654655
$phpDocParameterTypes[$param->var->name] ?? null,
@@ -899,13 +900,13 @@ private function processStmtNode(
899900
new ClassPropertyNode(
900901
$propertyName,
901902
$stmt->flags,
902-
$stmt->type,
903+
$stmt->type !== null ? ParserNodeTypeToPHPStanType::resolve($stmt->type, $scope->getClassReflection()) : null,
903904
$prop->default,
904905
$docComment,
905906
$phpDocType,
906907
false,
907908
false,
908-
$prop,
909+
$stmt,
909910
$isReadOnly,
910911
$scope->isInTrait(),
911912
$scope->getClassReflection()->isReadOnly(),

src/Dependency/DependencyResolver.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
use PHPStan\Reflection\ReflectionProvider;
2323
use PHPStan\Type\ClosureType;
2424
use PHPStan\Type\FileTypeMapper;
25-
use PHPStan\Type\ParserNodeTypeToPHPStanType;
2625
use PHPStan\Type\Type;
2726
use function array_merge;
2827
use function count;
@@ -85,9 +84,8 @@ public function resolveDependencies(Node $node, Scope $scope): NodeDependencies
8584
}
8685
}
8786
} elseif ($node instanceof ClassPropertyNode) {
88-
$nativeTypeNode = $node->getNativeType();
89-
if ($nativeTypeNode !== null) {
90-
$nativeType = ParserNodeTypeToPHPStanType::resolve($nativeTypeNode, $node->getClassReflection());
87+
$nativeType = $node->getNativeType();
88+
if ($nativeType !== null) {
9189
foreach ($nativeType->getReferencedClasses() as $referencedClass) {
9290
$this->addClassToDependencies($referencedClass, $dependenciesReflections);
9391
}

src/Node/ClassPropertyNode.php

+10-7
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
use PhpParser\Modifiers;
66
use PhpParser\Node;
77
use PhpParser\Node\Expr;
8-
use PhpParser\Node\Identifier;
9-
use PhpParser\Node\Name;
108
use PhpParser\NodeAbstract;
119
use PHPStan\Reflection\ClassReflection;
1210
use PHPStan\Type\Type;
@@ -20,13 +18,13 @@ final class ClassPropertyNode extends NodeAbstract implements VirtualNode
2018
public function __construct(
2119
private string $name,
2220
private int $flags,
23-
private Identifier|Name|Node\ComplexType|null $type,
21+
private ?Type $type,
2422
private ?Expr $default,
2523
private ?string $phpDoc,
2624
private ?Type $phpDocType,
2725
private bool $isPromoted,
2826
private bool $isPromotedFromTrait,
29-
Node $originalNode,
27+
private Node\Stmt\Property|Node\Param $originalNode,
3028
private bool $isReadonlyByPhpDoc,
3129
private bool $isDeclaredInTrait,
3230
private bool $isReadonlyClass,
@@ -113,12 +111,17 @@ public function isAllowedPrivateMutation(): bool
113111
return $this->isAllowedPrivateMutation;
114112
}
115113

114+
public function getNativeType(): ?Type
115+
{
116+
return $this->type;
117+
}
118+
116119
/**
117-
* @return Identifier|Name|Node\ComplexType|null
120+
* @return Node\Identifier|Node\Name|Node\ComplexType|null
118121
*/
119-
public function getNativeType()
122+
public function getNativeTypeNode()
120123
{
121-
return $this->type;
124+
return $this->originalNode->type;
122125
}
123126

124127
public function getClassReflection(): ClassReflection

src/Rules/PhpDoc/IncompatiblePropertyPhpDocTypeRule.php

+28-27
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
use PHPStan\Rules\Rule;
1111
use PHPStan\Rules\RuleErrorBuilder;
1212
use PHPStan\Type\Generic\TemplateType;
13-
use PHPStan\Type\ParserNodeTypeToPHPStanType;
1413
use PHPStan\Type\VerbosityLevel;
1514
use function array_merge;
1615
use function sprintf;
@@ -62,33 +61,35 @@ public function processNode(Node $node, Scope $scope): array
6261
))->identifier('property.unresolvableType')->build();
6362
}
6463

65-
$nativeType = ParserNodeTypeToPHPStanType::resolve($node->getNativeType(), $classReflection);
66-
$isSuperType = $nativeType->isSuperTypeOf($phpDocType);
67-
if ($isSuperType->no()) {
68-
$messages[] = RuleErrorBuilder::message(sprintf(
69-
'%s for property %s::$%s with type %s is incompatible with native type %s.',
70-
$description,
71-
$classReflection->getDisplayName(),
72-
$propertyName,
73-
$phpDocType->describe(VerbosityLevel::typeOnly()),
74-
$nativeType->describe(VerbosityLevel::typeOnly()),
75-
))->identifier('property.phpDocType')->build();
76-
77-
} elseif ($isSuperType->maybe()) {
78-
$errorBuilder = RuleErrorBuilder::message(sprintf(
79-
'%s for property %s::$%s with type %s is not subtype of native type %s.',
80-
$description,
81-
$classReflection->getDisplayName(),
82-
$propertyName,
83-
$phpDocType->describe(VerbosityLevel::typeOnly()),
84-
$nativeType->describe(VerbosityLevel::typeOnly()),
85-
))->identifier('property.phpDocType');
86-
87-
if ($phpDocType instanceof TemplateType) {
88-
$errorBuilder->tip(sprintf('Write @template %s of %s to fix this.', $phpDocType->getName(), $nativeType->describe(VerbosityLevel::typeOnly())));
64+
$nativeType = $node->getNativeType();
65+
if ($nativeType !== null) {
66+
$isSuperType = $nativeType->isSuperTypeOf($phpDocType);
67+
if ($isSuperType->no()) {
68+
$messages[] = RuleErrorBuilder::message(sprintf(
69+
'%s for property %s::$%s with type %s is incompatible with native type %s.',
70+
$description,
71+
$classReflection->getDisplayName(),
72+
$propertyName,
73+
$phpDocType->describe(VerbosityLevel::typeOnly()),
74+
$nativeType->describe(VerbosityLevel::typeOnly()),
75+
))->identifier('property.phpDocType')->build();
76+
77+
} elseif ($isSuperType->maybe()) {
78+
$errorBuilder = RuleErrorBuilder::message(sprintf(
79+
'%s for property %s::$%s with type %s is not subtype of native type %s.',
80+
$description,
81+
$classReflection->getDisplayName(),
82+
$propertyName,
83+
$phpDocType->describe(VerbosityLevel::typeOnly()),
84+
$nativeType->describe(VerbosityLevel::typeOnly()),
85+
))->identifier('property.phpDocType');
86+
87+
if ($phpDocType instanceof TemplateType) {
88+
$errorBuilder->tip(sprintf('Write @template %s of %s to fix this.', $phpDocType->getName(), $nativeType->describe(VerbosityLevel::typeOnly())));
89+
}
90+
91+
$messages[] = $errorBuilder->build();
8992
}
90-
91-
$messages[] = $errorBuilder->build();
9293
}
9394

9495
$className = SprintfHelper::escapeFormatString($classReflection->getDisplayName());

src/Rules/Properties/OverridingPropertyRule.php

+4-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use PHPStan\Reflection\Php\PhpPropertyReflection;
1010
use PHPStan\Rules\Rule;
1111
use PHPStan\Rules\RuleErrorBuilder;
12-
use PHPStan\Type\ParserNodeTypeToPHPStanType;
1312
use PHPStan\Type\VerbosityLevel;
1413
use function array_merge;
1514
use function count;
@@ -104,8 +103,9 @@ public function processNode(Node $node, Scope $scope): array
104103
}
105104

106105
$typeErrors = [];
106+
$nativeType = $node->getNativeType();
107107
if ($prototype->hasNativeType()) {
108-
if ($node->getNativeType() === null) {
108+
if ($nativeType === null) {
109109
$typeErrors[] = RuleErrorBuilder::message(sprintf(
110110
'Property %s::$%s overriding property %s::$%s (%s) should also have native type %s.',
111111
$classReflection->getDisplayName(),
@@ -116,7 +116,6 @@ public function processNode(Node $node, Scope $scope): array
116116
$prototype->getNativeType()->describe(VerbosityLevel::typeOnly()),
117117
))->identifier('property.missingNativeType')->nonIgnorable()->build();
118118
} else {
119-
$nativeType = ParserNodeTypeToPHPStanType::resolve($node->getNativeType(), $classReflection);
120119
if (!$prototype->getNativeType()->equals($nativeType)) {
121120
$typeErrors[] = RuleErrorBuilder::message(sprintf(
122121
'Type %s of property %s::$%s is not the same as type %s of overridden property %s::$%s.',
@@ -129,12 +128,12 @@ public function processNode(Node $node, Scope $scope): array
129128
))->identifier('property.nativeType')->nonIgnorable()->build();
130129
}
131130
}
132-
} elseif ($node->getNativeType() !== null) {
131+
} elseif ($nativeType !== null) {
133132
$typeErrors[] = RuleErrorBuilder::message(sprintf(
134133
'Property %s::$%s (%s) overriding property %s::$%s should not have a native type.',
135134
$classReflection->getDisplayName(),
136135
$node->getName(),
137-
ParserNodeTypeToPHPStanType::resolve($node->getNativeType(), $classReflection)->describe(VerbosityLevel::typeOnly()),
136+
$nativeType->describe(VerbosityLevel::typeOnly()),
138137
$prototype->getDeclaringClass()->getDisplayName(),
139138
$node->getName(),
140139
))->identifier('property.extraNativeType')->nonIgnorable()->build();

src/Rules/Types/InvalidTypesInUnionRule.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,11 @@ private function processFunctionLikeNode(Node\FunctionLike $functionLike): array
6969
*/
7070
private function processClassPropertyNode(ClassPropertyNode $classPropertyNode): array
7171
{
72-
if (!$classPropertyNode->getNativeType() instanceof Node\ComplexType) {
72+
if (!$classPropertyNode->getNativeTypeNode() instanceof Node\ComplexType) {
7373
return [];
7474
}
7575

76-
return $this->processComplexType($classPropertyNode->getNativeType());
76+
return $this->processComplexType($classPropertyNode->getNativeTypeNode());
7777
}
7878

7979
/**

0 commit comments

Comments
 (0)