Skip to content

Commit 7a94671

Browse files
committed
Annotate array types for PHPStan
Most types where based on dumping the input/output object otherwise copied from other functions where the the output is either the input for the function or the other way around. This should make it easier for PHPStan to discover wrong or unused code. Also disabled scanning for the Test fixtures as we do the same things for the tests. Removed one generic php-stan line as this was fixed according to PHPStan itself. Further work can be done to change the Object arrays to be less generic, and rescrict that it would only implement our Deletable objects, for now this doesn't add enough new information compared to the work.
1 parent c98bb2a commit 7a94671

10 files changed

+60
-132
lines changed

phpstan-baseline.neon

Lines changed: 0 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -180,141 +180,11 @@ parameters:
180180
count: 1
181181
path: webapp/src/Controller/API/SubmissionController.php
182182

183-
-
184-
message: "#^Method App\\\\Controller\\\\BaseController\\:\\:buildDeleteTree\\(\\) has parameter \\$entities with no value type specified in iterable type array\\.$#"
185-
count: 1
186-
path: webapp/src/Controller/BaseController.php
187-
188-
-
189-
message: "#^Method App\\\\Controller\\\\BaseController\\:\\:buildDeleteTree\\(\\) has parameter \\$relations with no value type specified in iterable type array\\.$#"
190-
count: 1
191-
path: webapp/src/Controller/BaseController.php
192-
193-
-
194-
message: "#^Method App\\\\Controller\\\\BaseController\\:\\:buildDeleteTree\\(\\) return type has no value type specified in iterable type array\\.$#"
195-
count: 1
196-
path: webapp/src/Controller/BaseController.php
197-
198-
-
199-
message: "#^Method App\\\\Controller\\\\BaseController\\:\\:commitDeleteEntity\\(\\) has parameter \\$primaryKeyData with no value type specified in iterable type array\\.$#"
200-
count: 1
201-
path: webapp/src/Controller/BaseController.php
202-
203-
-
204-
message: "#^Method App\\\\Controller\\\\BaseController\\:\\:deleteEntities\\(\\) has parameter \\$entities with no value type specified in iterable type array\\.$#"
205-
count: 1
206-
path: webapp/src/Controller/BaseController.php
207-
208-
-
209-
message: "#^Method App\\\\Controller\\\\BaseController\\:\\:getDatabaseRelations\\(\\) has parameter \\$files with no value type specified in iterable type array\\.$#"
210-
count: 1
211-
path: webapp/src/Controller/BaseController.php
212-
213-
-
214-
message: "#^Method App\\\\Controller\\\\BaseController\\:\\:getDatabaseRelations\\(\\) return type has no value type specified in iterable type array\\.$#"
215-
count: 1
216-
path: webapp/src/Controller/BaseController.php
217-
218-
-
219-
message: "#^Method App\\\\Controller\\\\BaseController\\:\\:getDependentEntities\\(\\) has parameter \\$relations with no value type specified in iterable type array\\.$#"
220-
count: 1
221-
path: webapp/src/Controller/BaseController.php
222-
223-
-
224-
message: "#^Method App\\\\Controller\\\\BaseController\\:\\:getDependentEntities\\(\\) return type has no value type specified in iterable type array\\.$#"
225-
count: 1
226-
path: webapp/src/Controller/BaseController.php
227-
228-
-
229-
message: "#^PHPDoc tag @var for variable \\$delayedJudgings has no value type specified in iterable type array\\.$#"
230-
count: 1
231-
path: webapp/src/Controller/Jury/AnalysisController.php
232-
233-
-
234-
message: "#^Method App\\\\Controller\\\\Jury\\\\BalloonController\\:\\:areDefault\\(\\) has parameter \\$defaultCategories with no value type specified in iterable type array\\.$#"
235-
count: 1
236-
path: webapp/src/Controller/Jury/BalloonController.php
237-
238-
-
239-
message: "#^Method App\\\\Controller\\\\Jury\\\\BalloonController\\:\\:areDefault\\(\\) has parameter \\$filters with no value type specified in iterable type array\\.$#"
240-
count: 1
241-
path: webapp/src/Controller/Jury/BalloonController.php
242-
243183
-
244184
message: "#^Method App\\\\Controller\\\\Jury\\\\ClarificationController\\:\\:getClarificationFormData\\(\\) return type has no value type specified in iterable type array\\.$#"
245185
count: 1
246186
path: webapp/src/Controller/Jury/ClarificationController.php
247187

248-
-
249-
message: "#^Method App\\\\Controller\\\\Jury\\\\ContestController\\:\\:judgeRemaining\\(\\) has parameter \\$judgings with no value type specified in iterable type array\\.$#"
250-
count: 1
251-
path: webapp/src/Controller/Jury/ContestController.php
252-
253-
-
254-
message: "#^Method App\\\\Controller\\\\Jury\\\\ExecutableController\\:\\:dataForEditor\\(\\) return type has no value type specified in iterable type array\\.$#"
255-
count: 1
256-
path: webapp/src/Controller/Jury/ExecutableController.php
257-
258-
-
259-
message: "#^Method App\\\\Controller\\\\Jury\\\\LanguageController\\:\\:judgeRemaining\\(\\) has parameter \\$judgings with no value type specified in iterable type array\\.$#"
260-
count: 1
261-
path: webapp/src/Controller/Jury/LanguageController.php
262-
263-
-
264-
message: "#^Method App\\\\Controller\\\\Jury\\\\ProblemController\\:\\:addTestcasesToZip\\(\\) has parameter \\$testcases with no value type specified in iterable type array\\.$#"
265-
count: 1
266-
path: webapp/src/Controller/Jury/ProblemController.php
267-
268-
-
269-
message: "#^Method App\\\\Controller\\\\Jury\\\\ProblemController\\:\\:judgeRemaining\\(\\) has parameter \\$judgings with no value type specified in iterable type array\\.$#"
270-
count: 1
271-
path: webapp/src/Controller/Jury/ProblemController.php
272-
273-
-
274-
message: "#^Method App\\\\Controller\\\\Jury\\\\RejudgingController\\:\\:generateFlashMessagesForSkippedJudgings\\(\\) has parameter \\$skipped with no value type specified in iterable type array\\.$#"
275-
count: 1
276-
path: webapp/src/Controller/Jury/RejudgingController.php
277-
278-
-
279-
message: "#^Method App\\\\Controller\\\\Jury\\\\RejudgingController\\:\\:getStats\\(\\) return type has no value type specified in iterable type array\\.$#"
280-
count: 1
281-
path: webapp/src/Controller/Jury/RejudgingController.php
282-
283-
-
284-
message: "#^Method App\\\\Controller\\\\Jury\\\\SubmissionController\\:\\:determineFileChanged\\(\\) has parameter \\$files with no value type specified in iterable type array\\.$#"
285-
count: 1
286-
path: webapp/src/Controller/Jury/SubmissionController.php
287-
288-
-
289-
message: "#^Method App\\\\Controller\\\\Jury\\\\SubmissionController\\:\\:determineFileChanged\\(\\) has parameter \\$oldFiles with no value type specified in iterable type array\\.$#"
290-
count: 1
291-
path: webapp/src/Controller/Jury/SubmissionController.php
292-
293-
-
294-
message: "#^Method App\\\\Controller\\\\Jury\\\\SubmissionController\\:\\:determineFileChanged\\(\\) return type has no value type specified in iterable type array\\.$#"
295-
count: 1
296-
path: webapp/src/Controller/Jury/SubmissionController.php
297-
298-
-
299-
message: "#^Method App\\\\Controller\\\\Jury\\\\SubmissionController\\:\\:judgeRemaining\\(\\) has parameter \\$judgings with no value type specified in iterable type array\\.$#"
300-
count: 1
301-
path: webapp/src/Controller/Jury/SubmissionController.php
302-
303-
-
304-
message: "#^Method App\\\\Controller\\\\Jury\\\\SubmissionController\\:\\:maybeGetErrors\\(\\) has parameter \\$allErrors with no value type specified in iterable type array\\.$#"
305-
count: 1
306-
path: webapp/src/Controller/Jury/SubmissionController.php
307-
308-
-
309-
message: "#^Method App\\\\Controller\\\\Jury\\\\TeamCategoryController\\:\\:judgeRemaining\\(\\) has parameter \\$judgings with no value type specified in iterable type array\\.$#"
310-
count: 1
311-
path: webapp/src/Controller/Jury/TeamCategoryController.php
312-
313-
-
314-
message: "#^Method App\\\\DataFixtures\\\\Test\\\\RejudgingStatesFixture\\:\\:rejudgingStages\\(\\) return type has no value type specified in iterable type array\\.$#"
315-
count: 1
316-
path: webapp/src/DataFixtures/Test/RejudgingStatesFixture.php
317-
318188
-
319189
message: "#^Method App\\\\Entity\\\\ExternalRelationshipEntityInterface\\:\\:getExternalRelationships\\(\\) return type has no value type specified in iterable type array\\.$#"
320190
count: 1

phpstan.dist.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ parameters:
1818
-
1919
message: '#PHPDoc tag @var for variable .* has no value type specified in iterable type array#'
2020
path: webapp/tests
21+
-
22+
message: "#Method .* return type has no value type specified in iterable type array#"
23+
path: webapp/src/DataFixtures/Test
2124
includes:
2225
- phpstan-baseline.neon
2326
- lib/vendor/phpstan/phpstan-doctrine/extension.neon

webapp/src/Controller/BaseController.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ protected function saveEntity(
132132

133133
/**
134134
* Helper function to get the database structure for an object.
135+
*
136+
* @param string[] $files
137+
* @return array<string, array<array{'target': string, 'targetColumn': string, 'type': string}>>
135138
*/
136139
protected function getDatabaseRelations(array $files, EntityManagerInterface $entityManager): array
137140
{
@@ -166,6 +169,8 @@ protected function getDatabaseRelations(array $files, EntityManagerInterface $en
166169

167170
/**
168171
* Handle the actual removal of an entity and the dependencies in the database.
172+
*
173+
* @param int[] $primaryKeyData
169174
*/
170175
protected function commitDeleteEntity(
171176
object $entity,
@@ -268,6 +273,11 @@ protected function commitDeleteEntity(
268273
}
269274
}
270275

276+
/**
277+
* @param Object[] $entities
278+
* @param array<string, array<string, array{'target': string, 'targetColumn': string, 'type': string}>> $relations
279+
* @return array{0: bool, 1: array<int[]>, 2: string[]}
280+
*/
271281
protected function buildDeleteTree(
272282
array $entities,
273283
array $relations,
@@ -277,7 +287,6 @@ protected function buildDeleteTree(
277287
$propertyAccessor = PropertyAccess::createPropertyAccessor();
278288
$inflector = InflectorFactory::create()->build();
279289
$readableType = str_replace('_', ' ', Utils::tableForEntity($entities[0]));
280-
/** @phpstan-ignore-next-line */
281290
$metadata = $entityManager->getClassMetadata($entities[0]::class);
282291
$primaryKeyData = [];
283292
$messages = [];
@@ -353,6 +362,7 @@ protected function buildDeleteTree(
353362
/**
354363
* Perform delete operation for the given entities.
355364
*
365+
* @param Object[] $entities
356366
* @throws DBALException
357367
* @throws NoResultException
358368
* @throws NonUniqueResultException
@@ -426,6 +436,10 @@ protected function deleteEntities(
426436
return $this->render('jury/delete.html.twig', $data);
427437
}
428438

439+
/**
440+
* @param array<string, array<array{'target': string, 'targetColumn': string, 'type': string}>> $relations
441+
* @return string[]
442+
*/
429443
protected function getDependentEntities(string $entityClass, array $relations): array
430444
{
431445
$result = [];

webapp/src/Controller/Jury/AnalysisController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ public function indexAction(
4949

5050
$maxDelayedJudgings = 10;
5151
$delayedTimeDiff = 5;
52-
/** @var array $delayedJudgings */
52+
/** @var array<array{'submitid': int, 'judgingid': int, 'submittime': float,
53+
* 'timediff': float, 'num_judgings': int}> $delayedJudgings */
5354
$delayedJudgings = $em->createQueryBuilder()
5455
->from(Submission::class, 's')
5556
->innerJoin(Judging::class, 'j', Expr\Join::WITH, 's.submitid = j.submission')

webapp/src/Controller/Jury/BalloonController.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public function __construct(
2828
protected readonly EventLogService $eventLogService
2929
) {}
3030

31+
/**
32+
* @param array<string, array<string>> $filters
33+
* @param int[] $defaultCategories
34+
*/
3135
private function areDefault(array $filters, array $defaultCategories): bool {
3236
if (isset($filters['affiliation-id'])) {
3337
return false;

webapp/src/Controller/Jury/ExecutableController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,11 @@ public function deleteAction(Request $request, string $execId): Response
488488

489489
/**
490490
* Get the data to use for the executable editor.
491+
*
492+
* @return array{'executable': Executable, 'filenames': string[],
493+
* 'skippedBinary': array<array{filename: string, execfileid: int}>,
494+
* 'aceFilenames': string[], 'ranks': int[],
495+
* 'files': string[], 'executableBits': bool[]}
491496
*/
492497
protected function dataForEditor(Executable $executable): array
493498
{

webapp/src/Controller/Jury/JudgeRemainingTrait.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
namespace App\Controller\Jury;
44

55
use App\Entity\JudgeTask;
6+
use App\Entity\Judging;
67
use App\Entity\QueueTask;
78

89
trait JudgeRemainingTrait
910
{
11+
/**
12+
* @param Judging[] $judgings
13+
*/
1014
protected function judgeRemaining(array $judgings): void
1115
{
1216
$inProgress = [];

webapp/src/Controller/Jury/ProblemController.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,9 @@ public function addAction(Request $request): Response
10461046
]);
10471047
}
10481048

1049+
/**
1050+
* @param Testcase[] $testcases
1051+
*/
10491052
private function addTestcasesToZip(array $testcases, ZipArchive $zip, bool $isSample): void
10501053
{
10511054
$formatString = sprintf('data/%%s/%%0%dd', ceil(log10(count($testcases) + 1)));

webapp/src/Controller/Jury/RejudgingController.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,9 @@ public function createAction(Request $request): Response
779779
});
780780
}
781781

782+
/**
783+
* @param Judging[] $skipped
784+
*/
782785
private function generateFlashMessagesForSkippedJudgings(array $skipped): void
783786
{
784787
/** @var Judging $judging */
@@ -796,6 +799,18 @@ private function generateFlashMessagesForSkippedJudgings(array $skipped): void
796799
}
797800
}
798801

802+
/**
803+
* @return array{'judging_runs_differ': int[], 'judging_runs_differ_overflow': int,
804+
* 'runtime_spread': array<array{'submitid': int, 'rank': int,
805+
* 'spread': float, 'count': int,
806+
* 'verdict': string}>,
807+
* 'judgehost_stats': array<string, array{'judgehost': string, 'njudged': int,
808+
* 'avgrun': float, 'stddev': float,
809+
* 'avgduration': float}>,
810+
* 'judgings': array<array{'rejudgingid': int, 'judgingid': int, 'submitid': int,
811+
* 'hostname': string, 'result': string, 'runtime_avg': float|null,
812+
* 'ntestcases': int, 'duration': float}>}
813+
*/
799814
private function getStats(Rejudging $rejudging): array
800815
{
801816
$judgings = $this->em->createQueryBuilder()

webapp/src/Controller/Jury/SubmissionController.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,12 @@ public function verifyShadowDifferenceAction(
10981098
return $this->redirectToLocalReferrer($this->router, $request, $redirect);
10991099
}
11001100

1101+
/**
1102+
* @param SubmissionFile[] $files
1103+
* @param SubmissionFile[] $oldFiles
1104+
* @return array{'changed': string[], 'changedfiles': array<SubmissionFile[]>,
1105+
* 'unchanged': string[], 'added': string[], 'removed': string[]}
1106+
*/
11011107
protected function determineFileChanged(array $files, array $oldFiles): array
11021108
{
11031109
$result = [
@@ -1190,6 +1196,9 @@ public function createJudgeTasks(string $submitId): RedirectResponse
11901196
return $this->redirectToRoute('jury_submission', ['submitId' => $submitId]);
11911197
}
11921198

1199+
/**
1200+
* @param string[] $allErrors
1201+
*/
11931202
private function maybeGetErrors(string $type, string $expectedConfigString, string $observedConfigString, array &$allErrors): void
11941203
{
11951204
$expectedConfig = $this->dj->jsonDecode($expectedConfigString);

0 commit comments

Comments
 (0)