@@ -37,6 +37,67 @@ public function processNode(Node $node, Scope $scope): array
3737 $ errors = [];
3838
3939 foreach ($ functionArguments as $ argument ) {
40+ if (
41+ $ argument instanceof Node \Expr \PropertyFetch
42+ && $ argument ->name instanceof Node \Identifier
43+ ) {
44+ $ foundPropertyReflection = $ this ->propertyReflectionFinder ->findPropertyReflectionFromNode ($ argument , $ scope );
45+ if ($ foundPropertyReflection === null ) {
46+ continue ;
47+ }
48+
49+ $ propertyReflection = $ foundPropertyReflection ->getNativeReflection ();
50+ if ($ propertyReflection === null ) {
51+ continue ;
52+ }
53+
54+ if ($ propertyReflection ->isReadOnly () || $ propertyReflection ->isReadOnlyByPhpDoc ()) {
55+ $ errors [] = RuleErrorBuilder::message (
56+ sprintf (
57+ 'Cannot unset %s %s::$%s property. ' ,
58+ $ propertyReflection ->isReadOnly () ? 'readonly ' : '@readonly ' ,
59+ $ propertyReflection ->getDeclaringClass ()->getDisplayName (),
60+ $ foundPropertyReflection ->getName (),
61+ ),
62+ )
63+ ->line ($ argument ->getStartLine ())
64+ ->identifier ($ propertyReflection ->isReadOnly () ? 'unset.readOnlyProperty ' : 'unset.readOnlyPropertyByPhpDoc ' )
65+ ->build ();
66+ continue ;
67+ }
68+
69+ if ($ propertyReflection ->isHooked ()) {
70+ $ errors [] = RuleErrorBuilder::message (
71+ sprintf (
72+ 'Cannot unset hooked %s::$%s property. ' ,
73+ $ propertyReflection ->getDeclaringClass ()->getDisplayName (),
74+ $ foundPropertyReflection ->getName (),
75+ ),
76+ )
77+ ->line ($ argument ->getStartLine ())
78+ ->identifier ('unset.hookedProperty ' )
79+ ->build ();
80+ continue ;
81+ } elseif ($ this ->phpVersion ->supportsPropertyHooks ()) {
82+ if (
83+ !$ propertyReflection ->isPrivate ()
84+ && !$ propertyReflection ->isFinal ()->yes ()
85+ && !$ propertyReflection ->getDeclaringClass ()->isFinal ()
86+ ) {
87+ $ errors [] = RuleErrorBuilder::message (
88+ sprintf (
89+ 'Cannot unset property %s::$%s because it might have hooks in a subclass. ' ,
90+ $ propertyReflection ->getDeclaringClass ()->getDisplayName (),
91+ $ foundPropertyReflection ->getName (),
92+ ),
93+ )
94+ ->line ($ argument ->getStartLine ())
95+ ->identifier ('unset.possiblyHookedProperty ' )
96+ ->build ();
97+ continue ;
98+ }
99+ }
100+ }
40101 $ error = $ this ->canBeUnset ($ argument , $ scope );
41102 if ($ error === null ) {
42103 continue ;
@@ -78,63 +139,6 @@ private function canBeUnset(Node $node, Scope $scope): ?IdentifierRuleError
78139 }
79140
80141 return $ this ->canBeUnset ($ node ->var , $ scope );
81- } elseif (
82- $ node instanceof Node \Expr \PropertyFetch
83- && $ node ->name instanceof Node \Identifier
84- ) {
85- $ foundPropertyReflection = $ this ->propertyReflectionFinder ->findPropertyReflectionFromNode ($ node , $ scope );
86- if ($ foundPropertyReflection === null ) {
87- return null ;
88- }
89-
90- $ propertyReflection = $ foundPropertyReflection ->getNativeReflection ();
91- if ($ propertyReflection === null ) {
92- return null ;
93- }
94-
95- if ($ propertyReflection ->isReadOnly () || $ propertyReflection ->isReadOnlyByPhpDoc ()) {
96- return RuleErrorBuilder::message (
97- sprintf (
98- 'Cannot unset %s %s::$%s property. ' ,
99- $ propertyReflection ->isReadOnly () ? 'readonly ' : '@readonly ' ,
100- $ propertyReflection ->getDeclaringClass ()->getDisplayName (),
101- $ foundPropertyReflection ->getName (),
102- ),
103- )
104- ->line ($ node ->getStartLine ())
105- ->identifier ($ propertyReflection ->isReadOnly () ? 'unset.readOnlyProperty ' : 'unset.readOnlyPropertyByPhpDoc ' )
106- ->build ();
107- }
108-
109- if ($ propertyReflection ->isHooked ()) {
110- return RuleErrorBuilder::message (
111- sprintf (
112- 'Cannot unset hooked %s::$%s property. ' ,
113- $ propertyReflection ->getDeclaringClass ()->getDisplayName (),
114- $ foundPropertyReflection ->getName (),
115- ),
116- )
117- ->line ($ node ->getStartLine ())
118- ->identifier ('unset.hookedProperty ' )
119- ->build ();
120- } elseif ($ this ->phpVersion ->supportsPropertyHooks ()) {
121- if (
122- !$ propertyReflection ->isPrivate ()
123- && !$ propertyReflection ->isFinal ()->yes ()
124- && !$ propertyReflection ->getDeclaringClass ()->isFinal ()
125- ) {
126- return RuleErrorBuilder::message (
127- sprintf (
128- 'Cannot unset property %s::$%s because it might have hooks in a subclass. ' ,
129- $ propertyReflection ->getDeclaringClass ()->getDisplayName (),
130- $ foundPropertyReflection ->getName (),
131- ),
132- )
133- ->line ($ node ->getStartLine ())
134- ->identifier ('unset.possiblyHookedProperty ' )
135- ->build ();
136- }
137- }
138142 }
139143
140144 return null ;
0 commit comments