55
66use PhpParser \Node ;
77use PhpParser \Node \Arg ;
8+ use PhpParser \Node \Expr ;
89use PhpParser \Node \Expr \StaticCall ;
910use PhpParser \Node \Expr \Variable ;
1011use PhpParser \Node \Stmt ;
1112use PhpParser \Node \Stmt \ClassMethod ;
1213use PhpParser \Node \Stmt \Expression ;
1314use PhpParser \NodeVisitor ;
15+ use PHPStan \BetterReflection \Reflection \Adapter \ReflectionParameter ;
1416use PHPStan \Reflection \ClassReflection ;
1517use PHPStan \Reflection \ExtendedMethodReflection ;
1618use Rector \Enum \ObjectReference ;
19+ use Rector \PhpParser \Node \Value \ValueResolver ;
1720use Rector \PHPStan \ScopeFetcher ;
1821use Rector \PHPStanStaticTypeMapper \Enum \TypeKind ;
1922use Rector \Rector \AbstractRector ;
@@ -30,9 +33,14 @@ final class RemoveParentDelegatingConstructorRector extends AbstractRector
3033 * @readonly
3134 */
3235 private StaticTypeMapper $ staticTypeMapper ;
33- public function __construct (StaticTypeMapper $ staticTypeMapper )
36+ /**
37+ * @readonly
38+ */
39+ private ValueResolver $ valueResolver ;
40+ public function __construct (StaticTypeMapper $ staticTypeMapper , ValueResolver $ valueResolver )
3441 {
3542 $ this ->staticTypeMapper = $ staticTypeMapper ;
43+ $ this ->valueResolver = $ valueResolver ;
3644 }
3745 public function getRuleDefinition (): RuleDefinition
3846 {
@@ -187,8 +195,31 @@ private function areConstructorAndParentParameterTypesMatching(ClassMethod $clas
187195 if (!$ this ->nodeComparator ->areNodesEqual ($ parameterType , $ parentParameterType )) {
188196 return \false;
189197 }
198+ if (!$ param ->default instanceof Expr) {
199+ continue ;
200+ }
201+ if ($ this ->isDifferentDefaultValue ($ param ->default , $ extendedMethodReflection , $ index )) {
202+ return \false;
203+ }
190204 }
191205 }
192206 return \true;
193207 }
208+ private function isDifferentDefaultValue (Expr $ defaultExpr , ExtendedMethodReflection $ extendedMethodReflection , int $ index ): bool
209+ {
210+ $ methodName = $ extendedMethodReflection ->getName ();
211+ // native reflection is needed to get exact default value
212+ if ($ extendedMethodReflection ->getDeclaringClass ()->getNativeReflection ()->hasMethod ($ methodName )) {
213+ $ parentMethod = $ extendedMethodReflection ->getDeclaringClass ()->getNativeReflection ()->getMethod ($ methodName );
214+ $ nativeParentParameterReflection = $ parentMethod ->getParameters ()[$ index ] ?? null ;
215+ if (!$ nativeParentParameterReflection instanceof ReflectionParameter) {
216+ return \false;
217+ }
218+ $ parentDefault = $ nativeParentParameterReflection ->getDefaultValue ();
219+ if (!$ this ->valueResolver ->isValue ($ defaultExpr , $ parentDefault )) {
220+ return \true;
221+ }
222+ }
223+ return \false;
224+ }
194225}
0 commit comments