@@ -55,48 +55,64 @@ class Deprecation
55
55
public function __construct ($ message , array $ trace , $ file )
56
56
{
57
57
$ this ->trace = $ trace ;
58
-
59
- if ('trigger_error ' === (isset ($ trace [1 ]['function ' ]) ? $ trace [1 ]['function ' ] : null )
60
- && (DebugClassLoader::class === ($ class = (isset ($ trace [2 ]['class ' ]) ? $ trace [2 ]['class ' ] : null )) || LegacyDebugClassLoader::class === $ class )
61
- && 'checkClass ' === (isset ($ trace [2 ]['function ' ]) ? $ trace [2 ]['function ' ] : null )
62
- && null !== ($ extraFile = (isset ($ trace [2 ]['args ' ][1 ]) ? $ trace [2 ]['args ' ][1 ] : null ))
63
- && '' !== $ extraFile
64
- && false !== $ extraFile = realpath ($ extraFile )
65
- ) {
66
- $ this ->getOriginalFilesStack ();
67
- array_splice ($ this ->originalFilesStack , 2 , 1 , $ extraFile );
68
- }
69
-
70
58
$ this ->message = $ message ;
59
+
71
60
$ i = \count ($ trace );
72
61
while (1 < $ i && $ this ->lineShouldBeSkipped ($ trace [--$ i ])) {
73
62
// No-op
74
63
}
64
+
75
65
$ line = $ trace [$ i ];
76
66
$ this ->triggeringFile = $ file ;
77
- if (isset ($ line ['object ' ]) || isset ($ line ['class ' ])) {
78
- if (isset ($ line ['class ' ]) && 0 === strpos ($ line ['class ' ], SymfonyTestsListenerFor::class)) {
79
- set_error_handler (function () {});
80
- $ parsedMsg = unserialize ($ this ->message );
81
- restore_error_handler ();
82
- $ this ->message = $ parsedMsg ['deprecation ' ];
83
- $ this ->originClass = $ parsedMsg ['class ' ];
84
- $ this ->originMethod = $ parsedMsg ['method ' ];
85
- if (isset ($ parsedMsg ['files_stack ' ])) {
86
- $ this ->originalFilesStack = $ parsedMsg ['files_stack ' ];
87
- }
88
- // If the deprecation has been triggered via
89
- // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
90
- // then we need to use the serialized information to determine
91
- // if the error has been triggered from vendor code.
92
- if (isset ($ parsedMsg ['triggering_file ' ])) {
93
- $ this ->triggeringFile = $ parsedMsg ['triggering_file ' ];
67
+
68
+ for ($ j = 1 ; $ j < $ i ; ++$ j ) {
69
+ if (!isset ($ trace [$ j ]['function ' ], $ trace [1 + $ j ]['class ' ], $ trace [1 + $ j ]['args ' ][0 ])) {
70
+ continue ;
71
+ }
72
+
73
+ if ('trigger_error ' === $ trace [$ j ]['function ' ] && !isset ($ trace [$ j ]['class ' ])) {
74
+ if (\in_array ($ trace [1 + $ j ]['class ' ], [DebugClassLoader::class, LegacyDebugClassLoader::class], true )) {
75
+ $ class = $ trace [1 + $ j ]['args ' ][0 ];
76
+ $ this ->triggeringFile = isset ($ trace [1 + $ j ]['args ' ][1 ]) ? realpath ($ trace [1 + $ j ]['args ' ][1 ]) : (new \ReflectionClass ($ class ))->getFileName ();
77
+ $ this ->getOriginalFilesStack ();
78
+ array_splice ($ this ->originalFilesStack , 0 , $ j , [$ this ->triggeringFile ]);
94
79
}
95
80
81
+ break ;
82
+ }
83
+ }
84
+
85
+ if (isset ($ line ['object ' ]) || isset ($ line ['class ' ])) {
86
+ if (!isset ($ line ['class ' ], $ trace [$ i - 2 ]['function ' ]) || 0 !== strpos ($ line ['class ' ], SymfonyTestsListenerFor::class)) {
87
+ $ this ->originClass = isset ($ line ['object ' ]) ? \get_class ($ line ['object ' ]) : $ line ['class ' ];
88
+ $ this ->originMethod = $ line ['function ' ];
89
+
90
+ return ;
91
+ }
92
+
93
+ if ('trigger_error ' !== $ trace [$ i - 2 ]['function ' ] || isset ($ trace [$ i - 2 ]['class ' ])) {
94
+ $ this ->originClass = \get_class ($ line ['args ' ][0 ]);
95
+ $ this ->originMethod = $ line ['args ' ][0 ]->getName ();
96
+
96
97
return ;
97
98
}
98
- $ this ->originClass = isset ($ line ['object ' ]) ? \get_class ($ line ['object ' ]) : $ line ['class ' ];
99
- $ this ->originMethod = $ line ['function ' ];
99
+
100
+ set_error_handler (function () {});
101
+ $ parsedMsg = unserialize ($ this ->message );
102
+ restore_error_handler ();
103
+ $ this ->message = $ parsedMsg ['deprecation ' ];
104
+ $ this ->originClass = $ parsedMsg ['class ' ];
105
+ $ this ->originMethod = $ parsedMsg ['method ' ];
106
+ if (isset ($ parsedMsg ['files_stack ' ])) {
107
+ $ this ->originalFilesStack = $ parsedMsg ['files_stack ' ];
108
+ }
109
+ // If the deprecation has been triggered via
110
+ // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
111
+ // then we need to use the serialized information to determine
112
+ // if the error has been triggered from vendor code.
113
+ if (isset ($ parsedMsg ['triggering_file ' ])) {
114
+ $ this ->triggeringFile = $ parsedMsg ['triggering_file ' ];
115
+ }
100
116
}
101
117
}
102
118
@@ -130,7 +146,9 @@ public function originatingClass()
130
146
throw new \LogicException ('Check with originatesFromAnObject() before calling this method. ' );
131
147
}
132
148
133
- return $ this ->originClass ;
149
+ $ class = $ this ->originClass ;
150
+
151
+ return false !== strpos ($ class , "@anonymous \0" ) ? (get_parent_class ($ class ) ?: key (class_implements ($ class )) ?: 'class ' ).'@anonymous ' : $ class ;
134
152
}
135
153
136
154
/**
@@ -158,8 +176,7 @@ public function getMessage()
158
176
*/
159
177
public function isLegacy ()
160
178
{
161
- $ class = $ this ->originatingClass ();
162
- if ((new \ReflectionClass ($ class ))->isInternal ()) {
179
+ if (!$ this ->originClass || (new \ReflectionClass ($ this ->originClass ))->isInternal ()) {
163
180
return false ;
164
181
}
165
182
@@ -168,8 +185,8 @@ public function isLegacy()
168
185
return 0 === strpos ($ method , 'testLegacy ' )
169
186
|| 0 === strpos ($ method , 'provideLegacy ' )
170
187
|| 0 === strpos ($ method , 'getLegacy ' )
171
- || strpos ($ class , '\Legacy ' )
172
- || \in_array ('legacy ' , Test::getGroups ($ class , $ method ), true );
188
+ || strpos ($ this -> originClass , '\Legacy ' )
189
+ || \in_array ('legacy ' , Test::getGroups ($ this -> originClass , $ method ), true );
173
190
}
174
191
175
192
/**
@@ -195,11 +212,10 @@ public function isMuted()
195
212
*/
196
213
public function getType ()
197
214
{
198
- $ triggeringFilePathType = $ this ->getPathType ($ this ->triggeringFile );
199
- if (self ::PATH_TYPE_SELF === $ triggeringFilePathType ) {
215
+ if (self ::PATH_TYPE_SELF === $ pathType = $ this ->getPathType ($ this ->triggeringFile )) {
200
216
return self ::TYPE_SELF ;
201
217
}
202
- if (self ::PATH_TYPE_UNDETERMINED === $ triggeringFilePathType ) {
218
+ if (self ::PATH_TYPE_UNDETERMINED === $ pathType ) {
203
219
return self ::TYPE_UNDETERMINED ;
204
220
}
205
221
$ erroringFile = $ erroringPackage = null ;
@@ -208,10 +224,10 @@ public function getType()
208
224
if ('- ' === $ file || 'Standard input code ' === $ file || !realpath ($ file )) {
209
225
continue ;
210
226
}
211
- if (self ::PATH_TYPE_SELF === $ this ->getPathType ($ file )) {
227
+ if (self ::PATH_TYPE_SELF === $ pathType = $ this ->getPathType ($ file )) {
212
228
return self ::TYPE_DIRECT ;
213
229
}
214
- if (self ::PATH_TYPE_UNDETERMINED === $ this -> getPathType ( $ file ) ) {
230
+ if (self ::PATH_TYPE_UNDETERMINED === $ pathType ) {
215
231
return self ::TYPE_UNDETERMINED ;
216
232
}
217
233
if (null !== $ erroringFile && null !== $ erroringPackage ) {
@@ -233,7 +249,7 @@ private function getOriginalFilesStack()
233
249
if (null === $ this ->originalFilesStack ) {
234
250
$ this ->originalFilesStack = [];
235
251
foreach ($ this ->trace as $ frame ) {
236
- if (!isset ($ frame ['file ' ]) || \in_array ($ frame ['function ' ], ['require ' , 'require_once ' , 'include ' , 'include_once ' ], true )) {
252
+ if (!isset ($ frame ['file ' ], $ frame [ ' function ' ] ) || (! isset ( $ frame [ ' class ' ]) && \in_array ($ frame ['function ' ], ['require ' , 'require_once ' , 'include ' , 'include_once ' ], true ) )) {
237
253
continue ;
238
254
}
239
255
@@ -259,13 +275,10 @@ private function getPackage($path)
259
275
$ relativePath = substr ($ path , \strlen ($ vendorRoot ) + 1 );
260
276
$ vendor = strstr ($ relativePath , \DIRECTORY_SEPARATOR , true );
261
277
if (false === $ vendor ) {
262
- throw new \ RuntimeException ( sprintf ( ' Could not find directory separator "%s" in path "%s". ' , \ DIRECTORY_SEPARATOR , $ relativePath )) ;
278
+ return ' symfony ' ;
263
279
}
264
280
265
- return rtrim ($ vendor .'/ ' .strstr (substr (
266
- $ relativePath ,
267
- \strlen ($ vendor ) + 1
268
- ), \DIRECTORY_SEPARATOR , true ), '/ ' );
281
+ return rtrim ($ vendor .'/ ' .strstr (substr ($ relativePath , \strlen ($ vendor ) + 1 ), \DIRECTORY_SEPARATOR , true ), '/ ' );
269
282
}
270
283
}
271
284
@@ -279,6 +292,13 @@ private static function getVendors()
279
292
{
280
293
if (null === self ::$ vendors ) {
281
294
self ::$ vendors = $ paths = [];
295
+ self ::$ vendors [] = \dirname (__DIR__ ).\DIRECTORY_SEPARATOR .'Legacy ' ;
296
+ if (class_exists (DebugClassLoader::class, false )) {
297
+ self ::$ vendors [] = \dirname ((new \ReflectionClass (DebugClassLoader::class))->getFileName ());
298
+ }
299
+ if (class_exists (LegacyDebugClassLoader::class, false )) {
300
+ self ::$ vendors [] = \dirname ((new \ReflectionClass (LegacyDebugClassLoader::class))->getFileName ());
301
+ }
282
302
foreach (get_declared_classes () as $ class ) {
283
303
if ('C ' === $ class [0 ] && 0 === strpos ($ class , 'ComposerAutoloaderInit ' )) {
284
304
$ r = new \ReflectionClass ($ class );
@@ -354,10 +374,9 @@ public function toString()
354
374
$ reflection ->setAccessible (true );
355
375
$ reflection ->setValue ($ exception , $ this ->trace );
356
376
357
- return 'deprecation triggered by ' .$ this ->originatingClass ().':: ' .$ this ->originatingMethod ().': ' .
358
- "\n" .$ this ->message .
359
- "\nStack trace: " .
360
- "\n" .str_replace (' ' .getcwd ().\DIRECTORY_SEPARATOR , ' ' , $ exception ->getTraceAsString ()).
361
- "\n" ;
377
+ return ($ this ->originatesFromAnObject () ? 'deprecation triggered by ' .$ this ->originatingClass ().':: ' .$ this ->originatingMethod ().": \n" : '' )
378
+ .$ this ->message ."\n"
379
+ ."Stack trace: \n"
380
+ .str_replace (' ' .getcwd ().\DIRECTORY_SEPARATOR , ' ' , $ exception ->getTraceAsString ())."\n" ;
362
381
}
363
382
}
0 commit comments