@@ -41,14 +41,23 @@ public function allowThrowInBaseClass(callable $callable): void
41
41
42
42
class FirstClassCallableTest extends BaseCallableTest {
43
43
44
- public function testDeclarations (): void
44
+ public function testDeclarations1 (): void
45
45
{
46
46
$ this ->noop (...);
47
+ }
47
48
49
+ public function testDeclarations2 (): void
50
+ {
48
51
$ this ->throws (...); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
52
+ }
49
53
54
+ public function testDeclarations3 (): void
55
+ {
50
56
// $this?->throws(...); // https://github.com/phpstan/phpstan/issues/9746
57
+ }
51
58
59
+ public function testDeclarations4 (): void
60
+ {
52
61
throwing_function (...); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
53
62
}
54
63
@@ -62,27 +71,51 @@ public function testExplicitExecution2(): void
62
71
(throwing_function (...))();
63
72
}
64
73
65
- public function testPassedCallbacks (): void
74
+ public function testPassedCallbacksA1 (): void
66
75
{
67
76
$ this ->immediateThrow (null , $ this ->throws (...));
77
+ }
68
78
79
+ public function testPassedCallbacksA2 (): void
80
+ {
69
81
array_map ($ this ->throws (...), []);
82
+ }
70
83
84
+ public function testPassedCallbacksA3 (): void
85
+ {
71
86
array_map (throwing_function (...), []);
87
+ }
72
88
89
+ public function testPassedCallbacksA4 (): void
90
+ {
73
91
$ this ->allowThrow (42 , $ this ->throws (...));
92
+ }
74
93
94
+ public function testPassedCallbacksA5 (): void
95
+ {
75
96
$ this ->allowThrow (42 , throwing_function (...));
97
+ }
76
98
99
+ public function testPassedCallbacksA6 (): void
100
+ {
77
101
$ this ->immediateThrow (
78
102
$ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
79
103
function () {},
80
104
);
105
+ }
81
106
107
+ public function testPassedCallbacksA7 (): void
108
+ {
82
109
$ this ->allowThrowInBaseClass (throwing_function (...));
110
+ }
83
111
112
+ public function testPassedCallbacksA8 (): void
113
+ {
84
114
$ this ->allowThrowInInterface (throwing_function (...));
115
+ }
85
116
117
+ public function testPassedCallbacksA9 (): void
118
+ {
86
119
$ this ->denied ($ this ->throws (...)); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
87
120
}
88
121
@@ -124,20 +157,29 @@ public function allowThrow(int $dummy, callable $callable): void
124
157
125
158
class ClosureTest extends BaseCallableTest {
126
159
127
- public function testDeclarations (): void
160
+ public function testDeclarationsB1 (): void
128
161
{
129
162
$ fn = function () {
130
163
throw new CheckedException (); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in closure!
131
164
};
165
+ }
132
166
167
+ public function testDeclarationsB2 (): void
168
+ {
133
169
$ fn2 = function () {
134
170
$ this ->throws (); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in closure!
135
171
};
172
+ }
136
173
174
+ public function testDeclarationsB3 (): void
175
+ {
137
176
$ fn3 = function () {
138
177
$ this ->noop (); // implicit throw is ignored
139
178
};
179
+ }
140
180
181
+ public function testDeclarationsB4 (): void
182
+ {
141
183
$ fn4 = function (callable $ c ) {
142
184
$ c (); // implicit throw is ignored (https://github.com/phpstan/phpstan/issues/9779)
143
185
};
@@ -150,58 +192,91 @@ public function testExplicitExecution(): void
150
192
})();
151
193
}
152
194
153
- public function testPassedCallbacks (): void
195
+ public function testPassedCallbacks1 (): void
154
196
{
155
197
$ this ->immediateThrow (function () {
156
198
throw new CheckedException ();
157
199
});
200
+ }
158
201
202
+ public function testPassedCallbacks2 (): void
203
+ {
159
204
$ self = $ this ; // self is unknown variable in scope of the closure
160
205
$ self ->immediateThrow (function () {
161
206
throw new CheckedException ();
162
207
});
208
+ }
163
209
210
+ public function testPassedCallbacks3 (): void
211
+ {
164
212
array_map (function () {
165
213
throw new CheckedException ();
166
214
}, []);
215
+ }
167
216
217
+ public function testPassedCallbacks4 (): void
218
+ {
168
219
array_map (function () {
169
220
$ this ->throws ();
170
221
}, []);
222
+ }
171
223
224
+ public function testPassedCallbacks5 (): void
225
+ {
172
226
$ this ->allowThrow (function () {
173
227
$ this ->throws ();
174
228
});
229
+ }
175
230
231
+ public function testPassedCallbacks6 (): void
232
+ {
176
233
$ this ->immediateThrow (
177
234
function () {},
178
235
function () {
179
236
throw new CheckedException (); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in closure!
180
237
},
181
238
);
239
+ }
182
240
241
+ public function testPassedCallbacks7 (): void
242
+ {
183
243
$ this ->immediateThrow (
184
244
denied: function () {},
185
245
);
246
+ }
186
247
248
+ public function testPassedCallbacks8 (): void
249
+ {
187
250
$ this ->immediateThrow (
188
251
denied: function () {
189
252
throw new CheckedException (); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in closure!
190
253
},
191
254
);
255
+ }
192
256
257
+ public function testPassedCallbacks9 (): void
258
+ {
193
259
$ this ->allowThrowInBaseClass (function () {
194
260
$ this ->throws ();
195
261
});
262
+ }
196
263
264
+ public function testPassedCallbacks10 (): void
265
+ {
197
266
$ this ->allowThrowInInterface (function () {
198
267
$ this ->throws ();
199
268
});
269
+ }
200
270
271
+ public function testPassedCallbacks11 (): void
272
+ {
201
273
$ this ->denied (function () {
202
274
throw new CheckedException (); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in closure!
203
275
});
276
+ }
204
277
278
+ public function testPassedCallbacks12 (): void
279
+ {
205
280
$ this ?->denied(function () {
206
281
$ this ->throws (); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in closure!
207
282
});
@@ -250,14 +325,23 @@ public function __construct($callable)
250
325
new self (fn () => throw new CheckedException ());
251
326
}
252
327
253
- public function testDeclarations (): void
328
+ public function testDeclarationsC1 (): void
254
329
{
255
330
$ fn = fn () => throw new CheckedException (); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in arrow function!
331
+ }
256
332
333
+ public function testDeclarationsC2 (): void
334
+ {
257
335
$ fn2 = fn () => $ this ->throws (); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in arrow function!
336
+ }
258
337
338
+ public function testDeclarationsC3 (): void
339
+ {
259
340
$ fn3 = fn () => $ this ->noop (); // implicit throw is ignored
341
+ }
260
342
343
+ public function testDeclarationsC4 (): void
344
+ {
261
345
$ fn4 = fn (callable $ c ) => $ c (); // implicit throw is ignored (https://github.com/phpstan/phpstan/issues/9779)
262
346
}
263
347
@@ -266,22 +350,43 @@ public function testExplicitExecution(): void
266
350
(fn () => throw new CheckedException ())();
267
351
}
268
352
269
- public function testPassedCallbacks (): void
353
+ public function testPassedCallbacksC1 (): void
270
354
{
271
355
$ this ->immediateThrow (fn () => throw new CheckedException ());
356
+ }
272
357
358
+ public function testPassedCallbacksC2 (): void
359
+ {
273
360
array_map (fn () => throw new CheckedException (), []);
361
+ }
274
362
363
+ public function testPassedCallbacksC3 (): void
364
+ {
275
365
array_map (fn () => $ this ->throws (), []);
366
+ }
276
367
368
+ public function testPassedCallbacksC4 (): void
369
+ {
277
370
$ this ->allowThrow (fn () => $ this ->throws ());
371
+ }
278
372
373
+ public function testPassedCallbacksC5 (): void
374
+ {
279
375
$ this ->allowThrowInBaseClass (fn () => $ this ->throws ());
376
+ }
280
377
378
+ public function testPassedCallbacksC6 (): void
379
+ {
281
380
$ this ->allowThrowInInterface (fn () => $ this ->throws ());
381
+ }
282
382
383
+ public function testPassedCallbacksC7 (): void
384
+ {
283
385
$ this ->denied (fn () => throw new CheckedException ()); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in arrow function!
386
+ }
284
387
388
+ public function testPassedCallbacksC8 (): void
389
+ {
285
390
$ this ?->denied(fn () => throw new CheckedException ()); // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in arrow function!
286
391
}
287
392
@@ -323,40 +428,55 @@ public function allowThrow(callable $callable): void
323
428
324
429
class ArgumentSwappingTest {
325
430
326
- public function test ()
431
+ public function testD1 (): void
327
432
{
328
433
$ this ->call (
329
434
$ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
330
435
$ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
331
436
$ this ->throws (...),
332
437
$ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
333
438
);
439
+ }
334
440
441
+ public function testD2 (): void
442
+ {
335
443
$ this ->call (
336
444
second: $ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
337
445
first: $ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
338
446
third: $ this ->throws (...),
339
447
);
448
+ }
340
449
450
+ public function testD3 (): void
451
+ {
341
452
$ this ->call (
342
453
forth: $ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
343
454
first: $ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
344
455
);
456
+ }
345
457
458
+ public function testD4 (): void
459
+ {
346
460
$ this ->call (
347
461
$ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
348
462
forth: $ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
349
463
second: $ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
350
464
third: $ this ->throws (...),
351
465
);
466
+ }
352
467
468
+ public function testD5 (): void
469
+ {
353
470
$ this ->call (
354
471
$ this ->noop (...),
355
472
$ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
356
473
forth: $ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
357
474
third: $ this ->noop (...),
358
475
);
476
+ }
359
477
478
+ public function testD6 (): void
479
+ {
360
480
// this is not yet supported, the rule do not see this as argument pass
361
481
$ this ->call (... [
362
482
'third ' => $ this ->throws (...), // error: Throwing checked exception ForbidCheckedExceptionInCallableRule\CheckedException in first-class-callable!
0 commit comments