26
26
use PhpParser \Node \InterpolatedStringPart ;
27
27
use PhpParser \Node \Name ;
28
28
use PhpParser \Node \Name \FullyQualified ;
29
+ use PhpParser \Node \PropertyHook ;
29
30
use PhpParser \Node \Scalar \String_ ;
31
+ use PhpParser \Node \Stmt \ClassMethod ;
32
+ use PhpParser \Node \Stmt \Function_ ;
30
33
use PhpParser \NodeFinder ;
31
34
use PHPStan \Node \ExecutionEndNode ;
32
35
use PHPStan \Node \Expr \AlwaysRememberedExpr ;
52
55
use PHPStan \Php \PhpVersions ;
53
56
use PHPStan \PhpDoc \Tag \TemplateTag ;
54
57
use PHPStan \Reflection \Assertions ;
58
+ use PHPStan \Reflection \AttributeReflection ;
59
+ use PHPStan \Reflection \AttributeReflectionFactory ;
55
60
use PHPStan \Reflection \Callables \CallableParametersAcceptor ;
56
61
use PHPStan \Reflection \Callables \SimpleImpurePoint ;
57
62
use PHPStan \Reflection \Callables \SimpleThrowPoint ;
@@ -212,6 +217,7 @@ public function __construct(
212
217
private ConstantResolver $ constantResolver ,
213
218
private ScopeContext $ context ,
214
219
private PhpVersion $ phpVersion ,
220
+ private AttributeReflectionFactory $ attributeReflectionFactory ,
215
221
private int |array |null $ configPhpVersion ,
216
222
private bool $ declareStrictTypes = false ,
217
223
private PhpFunctionFromParserNodeReflection |null $ function = null ,
@@ -2974,6 +2980,7 @@ public function enterClassMethod(
2974
2980
$ this ->getRealParameterTypes ($ classMethod ),
2975
2981
array_map (fn (Type $ type ): Type => $ this ->transformStaticType (TemplateTypeHelper::toArgument ($ type )), $ phpDocParameterTypes ),
2976
2982
$ this ->getRealParameterDefaultValues ($ classMethod ),
2983
+ $ this ->getParameterAttributes ($ classMethod ),
2977
2984
$ this ->transformStaticType ($ this ->getFunctionType ($ classMethod ->returnType , false , false )),
2978
2985
$ phpDocReturnType !== null ? $ this ->transformStaticType (TemplateTypeHelper::toArgument ($ phpDocReturnType )) : null ,
2979
2986
$ throwType ,
@@ -2990,6 +2997,7 @@ public function enterClassMethod(
2990
2997
$ immediatelyInvokedCallableParameters ,
2991
2998
array_map (fn (Type $ type ): Type => $ this ->transformStaticType (TemplateTypeHelper::toArgument ($ type )), $ phpDocClosureThisTypeParameters ),
2992
2999
$ isConstructor ,
3000
+ $ this ->attributeReflectionFactory ->fromAttrGroups ($ classMethod ->attrGroups , InitializerExprContext::fromStubParameter ($ this ->getClassReflection ()->getName (), $ this ->getFile (), $ classMethod )),
2993
3001
),
2994
3002
!$ classMethod ->isStatic (),
2995
3003
);
@@ -3059,6 +3067,7 @@ public function enterPropertyHook(
3059
3067
$ realParameterTypes ,
3060
3068
$ phpDocParameterTypes ,
3061
3069
[],
3070
+ $ this ->getParameterAttributes ($ hook ),
3062
3071
$ realReturnType ,
3063
3072
$ phpDocReturnType ,
3064
3073
$ throwType ,
@@ -3075,6 +3084,7 @@ public function enterPropertyHook(
3075
3084
[],
3076
3085
[],
3077
3086
false ,
3087
+ $ this ->attributeReflectionFactory ->fromAttrGroups ($ hook ->attrGroups , InitializerExprContext::fromStubParameter ($ this ->getClassReflection ()->getName (), $ this ->getFile (), $ hook )),
3078
3088
),
3079
3089
true ,
3080
3090
);
@@ -3138,6 +3148,27 @@ private function getRealParameterDefaultValues(Node\FunctionLike $functionLike):
3138
3148
return $ realParameterDefaultValues ;
3139
3149
}
3140
3150
3151
+ /**
3152
+ * @return array<string, list<AttributeReflection>>
3153
+ */
3154
+ private function getParameterAttributes (ClassMethod |Function_ |PropertyHook $ functionLike ): array
3155
+ {
3156
+ $ parameterAttributes = [];
3157
+ $ className = null ;
3158
+ if ($ this ->isInClass ()) {
3159
+ $ className = $ this ->getClassReflection ()->getName ();
3160
+ }
3161
+ foreach ($ functionLike ->getParams () as $ parameter ) {
3162
+ if (!$ parameter ->var instanceof Variable || !is_string ($ parameter ->var ->name )) {
3163
+ throw new ShouldNotHappenException ();
3164
+ }
3165
+
3166
+ $ parameterAttributes [$ parameter ->var ->name ] = $ this ->attributeReflectionFactory ->fromAttrGroups ($ parameter ->attrGroups , InitializerExprContext::fromStubParameter ($ className , $ this ->getFile (), $ functionLike ));
3167
+ }
3168
+
3169
+ return $ parameterAttributes ;
3170
+ }
3171
+
3141
3172
/**
3142
3173
* @api
3143
3174
* @param Type[] $phpDocParameterTypes
@@ -3171,6 +3202,7 @@ public function enterFunction(
3171
3202
$ this ->getRealParameterTypes ($ function ),
3172
3203
array_map (static fn (Type $ type ): Type => TemplateTypeHelper::toArgument ($ type ), $ phpDocParameterTypes ),
3173
3204
$ this ->getRealParameterDefaultValues ($ function ),
3205
+ $ this ->getParameterAttributes ($ function ),
3174
3206
$ this ->getFunctionType ($ function ->returnType , $ function ->returnType === null , false ),
3175
3207
$ phpDocReturnType !== null ? TemplateTypeHelper::toArgument ($ phpDocReturnType ) : null ,
3176
3208
$ throwType ,
@@ -3184,6 +3216,7 @@ public function enterFunction(
3184
3216
array_map (static fn (Type $ type ): Type => TemplateTypeHelper::toArgument ($ type ), $ parameterOutTypes ),
3185
3217
$ immediatelyInvokedCallableParameters ,
3186
3218
$ phpDocClosureThisTypeParameters ,
3219
+ $ this ->attributeReflectionFactory ->fromAttrGroups ($ function ->attrGroups , InitializerExprContext::fromStubParameter (null , $ this ->getFile (), $ function )),
3187
3220
),
3188
3221
false ,
3189
3222
);
0 commit comments