2727class NameResolver extends NodeVisitorAbstract
2828{
2929 /** @var NameContext Naming context */
30- protected $ nameContext ;
30+ protected NameContext $ nameContext ;
3131
3232 /** @var bool Whether to preserve original names */
33- protected $ preserveOriginalNames ;
33+ protected bool $ preserveOriginalNames ;
3434
3535 /** @var bool Whether to replace resolved nodes in place, or to add resolvedNode attributes */
36- protected $ replaceNodes ;
36+ protected bool $ replaceNodes ;
3737
3838 /** @var bool Whether to parse DocBlock Custom Annotations */
3939 protected $ parseCustomAnnotations ;
@@ -55,8 +55,8 @@ class NameResolver extends NodeVisitorAbstract
5555 * namespacedName attribute, as usual.)
5656 * * parseCustomAnnotations (default true): Whether to parse DocBlock Custom Annotations.
5757 *
58- * @param ErrorHandler|null $errorHandler Error handler
59- * @param array $options Options
58+ * @param ErrorHandler|null $errorHandler Error handler
59+ * @param array{preserveOriginalNames?: bool, replaceNodes?: bool, parseCustomAnnotations?: bool} $options Options
6060 */
6161 public function __construct (?ErrorHandler $ errorHandler = null , array $ options = [])
6262 {
@@ -79,7 +79,7 @@ public function getNameContext(): NameContext
7979 return $ this ->nameContext ;
8080 }
8181
82- public function beforeTraverse (array $ nodes )
82+ public function beforeTraverse (array $ nodes ): ? array
8383 {
8484 $ this ->nameContext ->startNamespace ();
8585
@@ -110,6 +110,8 @@ public function enterNode(Node $node)
110110 $ this ->resolveAttrGroups ($ node );
111111 if (null !== $ node ->name ) {
112112 $ this ->addNamespacedName ($ node );
113+ } else {
114+ $ node ->namespacedName = null ;
113115 }
114116 } elseif ($ node instanceof Stmt \Interface_) {
115117 foreach ($ node ->extends as &$ interface ) {
@@ -134,7 +136,8 @@ public function enterNode(Node $node)
134136 $ this ->resolveSignature ($ node );
135137 $ this ->resolveAttrGroups ($ node );
136138 $ this ->addNamespacedName ($ node );
137- } elseif ($ node instanceof Stmt \ClassMethod
139+ } elseif (
140+ $ node instanceof Stmt \ClassMethod
138141 || $ node instanceof Expr \Closure
139142 || $ node instanceof Expr \ArrowFunction
140143 ) {
@@ -183,15 +186,25 @@ public function enterNode(Node $node)
183186 }
184187 }
185188 }
189+ } elseif ($ node instanceof Node \PropertyHook) {
190+ foreach ($ node ->params as $ param ) {
191+ $ param ->type = $ this ->resolveType ($ param ->type );
192+ $ this ->resolveAttrGroups ($ param );
193+ }
194+ $ this ->resolveAttrGroups ($ node );
186195 } elseif ($ node instanceof Stmt \Const_) {
187196 foreach ($ node ->consts as $ const ) {
188197 $ this ->addNamespacedName ($ const );
189198 }
190199 } elseif ($ node instanceof Stmt \ClassConst) {
200+ if (null !== $ node ->type ) {
201+ $ node ->type = $ this ->resolveType ($ node ->type );
202+ }
191203 $ this ->resolveAttrGroups ($ node );
192204 } elseif ($ node instanceof Stmt \EnumCase) {
193205 $ this ->resolveAttrGroups ($ node );
194- } elseif ($ node instanceof Expr \StaticCall
206+ } elseif (
207+ $ node instanceof Expr \StaticCall
195208 || $ node instanceof Expr \StaticPropertyFetch
196209 || $ node instanceof Expr \ClassConstFetch
197210 || $ node instanceof Expr \New_
@@ -234,8 +247,8 @@ public function enterNode(Node $node)
234247 /**
235248 * Resolve name, according to name resolver options.
236249 *
237- * @param Name $name Function or constant name to resolve
238- * @param int $type One of Stmt\Use_::TYPE_*
250+ * @param Name $name Function or constant name to resolve
251+ * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
239252 *
240253 * @return Name Resolved name, or original name with attribute
241254 */
@@ -307,10 +320,15 @@ protected function resolveAttrGroups(Node $node): void
307320 }
308321 }
309322
310- private function addAlias (Stmt \UseUse $ use , int $ type , ?Name $ prefix = null ): void
323+ /**
324+ * @param Stmt\Use_::TYPE_* $type
325+ * @param ?Name $prefix
326+ *
327+ * @psalm-suppress PossiblyNullArgument
328+ */
329+ private function addAlias (Node \UseItem $ use , int $ type , ?Name $ prefix = null ): void
311330 {
312331 // Add prefix for group uses
313- /** @var Name $name */
314332 $ name = $ prefix ? Name::concat ($ prefix , $ use ->name ) : $ use ->name ;
315333 // Type is determined either by individual element or whole use declaration
316334 $ type |= $ use ->type ;
@@ -364,10 +382,15 @@ private function resolveSignature($node): void
364382 * @psalm-suppress MissingParamType
365383 * @psalm-suppress PossiblyNullArgument
366384 * @psalm-suppress MissingReturnType
385+ * @psalm-suppress InvalidReturnStatement
386+ *
387+ * @template T of Node\Identifier|Name|Node\ComplexType|null
388+ *
389+ * @param T $node
367390 *
368- * @param mixed $node
391+ * @return T
369392 */
370- private function resolveType ($ node )
393+ private function resolveType (? Node $ node ): ? Node
371394 {
372395 if ($ node instanceof Name) {
373396 return $ this ->resolveClassName ($ node );
0 commit comments