Skip to content

Commit a61710f

Browse files
committed
Further steer PHPstan with docblocks
When CLICS has some extra fields those are now added for documentation. Only if there are many of those they've been left out. I've assumed that we can import runs which are still running so the {run_, contest_ & ''}time are still null so can even have been ommited. It seems that both runner & compiler are optional based on the examples in the CLICS documentation.
1 parent 43baf21 commit a61710f

File tree

3 files changed

+86
-99
lines changed

3 files changed

+86
-99
lines changed

phpstan-baseline.neon

Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -68,93 +68,3 @@ parameters:
6868
message: "#^Method App\\\\FosRestBundle\\\\FlattenExceptionHandler\\:\\:serializeToJson\\(\\) return type has no value type specified in iterable type array\\.$#"
6969
count: 1
7070
path: webapp/src/FosRestBundle/FlattenExceptionHandler.php
71-
72-
-
73-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:compareOrCreateValues\\(\\) has parameter \\$extraDiff with no value type specified in iterable type array\\.$#"
74-
count: 1
75-
path: webapp/src/Service/ExternalContestSourceService.php
76-
77-
-
78-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:compareOrCreateValues\\(\\) has parameter \\$values with no value type specified in iterable type array\\.$#"
79-
count: 1
80-
path: webapp/src/Service/ExternalContestSourceService.php
81-
82-
-
83-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:importClarification\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
84-
count: 1
85-
path: webapp/src/Service/ExternalContestSourceService.php
86-
87-
-
88-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:importFromContestArchive\\(\\) has parameter \\$eventsToSkip with no value type specified in iterable type array\\.$#"
89-
count: 1
90-
path: webapp/src/Service/ExternalContestSourceService.php
91-
92-
-
93-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:importJudgement\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
94-
count: 1
95-
path: webapp/src/Service/ExternalContestSourceService.php
96-
97-
-
98-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:importJudgementType\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
99-
count: 1
100-
path: webapp/src/Service/ExternalContestSourceService.php
101-
102-
-
103-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:importRun\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
104-
count: 1
105-
path: webapp/src/Service/ExternalContestSourceService.php
106-
107-
-
108-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:importSubmission\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
109-
count: 1
110-
path: webapp/src/Service/ExternalContestSourceService.php
111-
112-
-
113-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:validateAndUpdateContest\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
114-
count: 1
115-
path: webapp/src/Service/ExternalContestSourceService.php
116-
117-
-
118-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:validateAndUpdateGroup\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
119-
count: 1
120-
path: webapp/src/Service/ExternalContestSourceService.php
121-
122-
-
123-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:validateAndUpdateOrganization\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
124-
count: 1
125-
path: webapp/src/Service/ExternalContestSourceService.php
126-
127-
-
128-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:validateAndUpdateProblem\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
129-
count: 1
130-
path: webapp/src/Service/ExternalContestSourceService.php
131-
132-
-
133-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:validateAndUpdateTeam\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
134-
count: 1
135-
path: webapp/src/Service/ExternalContestSourceService.php
136-
137-
-
138-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:validateLanguage\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
139-
count: 1
140-
path: webapp/src/Service/ExternalContestSourceService.php
141-
142-
-
143-
message: "#^Property App\\\\Service\\\\ExternalContestSourceService\\:\\:\\$cachedApiInfoData type has no value type specified in iterable type array\\.$#"
144-
count: 1
145-
path: webapp/src/Service/ExternalContestSourceService.php
146-
147-
-
148-
message: "#^Property App\\\\Service\\\\ExternalContestSourceService\\:\\:\\$cachedContestData type has no value type specified in iterable type array\\.$#"
149-
count: 1
150-
path: webapp/src/Service/ExternalContestSourceService.php
151-
152-
-
153-
message: "#^Property App\\\\Service\\\\ExternalContestSourceService\\:\\:\\$pendingEvents type has no value type specified in iterable type array\\.$#"
154-
count: 1
155-
path: webapp/src/Service/ExternalContestSourceService.php
156-
157-
-
158-
message: "#^Method App\\\\Service\\\\StatisticsService\\:\\:getGroupedProblemsStats\\(\\) return type has no value type specified in iterable type array\\.$#"
159-
count: 1
160-
path: webapp/src/Service/StatisticsService.php

webapp/src/Service/ExternalContestSourceService.php

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,18 @@ class ExternalContestSourceService
4646
protected ?ExternalContestSource $source = null;
4747

4848
protected bool $contestLoaded = false;
49+
/**
50+
* @var array{scoreboard_type: string, external_id: string, end_time: string, duration: string, name: string,
51+
* scoreboard_freeze_duration: string, id: string, allow_submit: bool, allow_submit: bool,
52+
* penalty_time: int, start_time?: string|null, formal_name?: string|null, shortname?: string|null,
53+
* scoreboard_thaw_time?: string, warning_message?: string|null} $cachedContestData
54+
*/
4955
protected ?array $cachedContestData = null;
56+
/**
57+
* @var array{version: string, version_url: string, name: string,
58+
* provider?: array{name?: string, build_date?: string, version?: string},
59+
* domjudge?: array{apiversion: int, version: string, environment: string, doc_url: string}} $cachedApiInfoData
60+
*/
5061
protected ?array $cachedApiInfoData = null;
5162
protected ?string $loadingError = null;
5263
protected bool $shouldStopReading = false;
@@ -65,6 +76,17 @@ class ExternalContestSourceService
6576
* - The first dimension is the type of the dependent event type
6677
* - The second dimension is the (external) ID of the dependent event
6778
* - The third dimension contains an array of all events that should be processed
79+
*
80+
* @var array<string, array<string, array{token?: string, id: string, type: string, time: string, op?: string,
81+
* end_of_updates?: bool,
82+
* data?: array{run_time?: float, time?: string, contest_time?: string,
83+
* ordinal?: int, id: string, judgement_id?: string,
84+
* judgement_type_id: string|null, max_run_time?: float|null,
85+
* start_time: string, start_contest_time?: string, end_time?: string|null,
86+
* end_contest_time?: string|null, submission_id: string,
87+
* output_compile_as_string: null, language_id?: string, externalid?: null,
88+
* team_id: string, problem_id?: string, entry_point?: string|null,
89+
* old_result?: null, files?: array{href: string}}|mixed[]}>> $pendingEvents
6890
*/
6991
protected array $pendingEvents = [
7092
// Initialize it with all types that can be a dependent event.
@@ -411,6 +433,9 @@ protected function importFromCcsApi(array $eventsToSkip, ?callable $progressRepo
411433
}
412434
}
413435

436+
/**
437+
* @param string[] $eventsToSkip
438+
*/
414439
protected function importFromContestArchive(array $eventsToSkip, ?callable $progressReporter = null): bool
415440
{
416441
$file = fopen($this->source->getSource() . '/event-feed.ndjson', 'r');
@@ -580,7 +605,7 @@ protected function loadContest(): void
580605
* id: string, judgement_id?: string, judgement_type_id: string|null,
581606
* max_run_time?: float|null, start_time: string, start_contest_time?: string,
582607
* end_time?: string|null, end_contest_time?: string|null, submission_id: string,
583-
* output_compile_as_string: null, language_id?: string, externalid?: null,
608+
* output_compile_as_string: null, language_id?: string, externalid?: string|null,
584609
* team_id: string, problem_id?: string, entry_point?: string|null, old_result?: null,
585610
* files?: array{href: string}}|mixed[]
586611
* } $event
@@ -684,6 +709,10 @@ public function importEvent(array $event, array $eventsToSkip): void
684709
}
685710

686711
/**
712+
* @param array{id: string, name: string, duration: string, scoreboard_type: string, penalty_time: int,
713+
* formal_name?: string, start_time?: string|null, countdown_pause_time?: int|null,
714+
* scoreboard_freeze_duration: string|null, scoreboard_thaw_time?: string|null,
715+
* banner: array{0: array{href: string, filename: string, mime: string, width: int, height: int}}} $data
687716
* @throws NonUniqueResultException
688717
*/
689718
protected function validateAndUpdateContest(string $entityType, ?string $eventId, string $operation, array $data): void
@@ -793,6 +822,9 @@ protected function validateAndUpdateContest(string $entityType, ?string $eventId
793822
$this->eventLog->log('contests', $contest->getCid(), EventLogService::ACTION_UPDATE, $this->getSourceContestId());
794823
}
795824

825+
/**
826+
* @param array{id: string, name: string, penalty: bool, solved: bool} $data description
827+
*/
796828
protected function importJudgementType(string $entityType, ?string $eventId, string $operation, array $data): void
797829
{
798830
if (!$this->warningIfUnsupported($operation, $eventId, $entityType, $data['id'], [EventLogService::ACTION_CREATE])) {
@@ -835,6 +867,12 @@ protected function importJudgementType(string $entityType, ?string $eventId, str
835867
$this->compareOrCreateValues($eventId, $entityType, $data['id'], $this->source->getContest(), [], $extraDiff, false);
836868
}
837869

870+
/**
871+
* @param array{id: string, name: string, entry_point_required: true, entry_point_name?: string|null,
872+
* extensions: string[],
873+
* compiler?: array{command: string, args?: string, version?: string, version_command?: string},
874+
* runner?: array{command: string, args?: string, version?: string, version_command?: string}} $data
875+
*/
838876
protected function validateLanguage(string $entityType, ?string $eventId, string $operation, array $data): void
839877
{
840878
if (!$this->warningIfUnsupported($operation, $eventId, $entityType, $data['id'], [EventLogService::ACTION_CREATE])) {
@@ -861,6 +899,10 @@ protected function validateLanguage(string $entityType, ?string $eventId, string
861899
}
862900
}
863901

902+
/**
903+
* @param array{id: string, name: string, icpc_id?: string|null, type?: string|null, location?: string|null,
904+
* hidden?: bool, sortorder?: int|null, color?: string|null} $data
905+
*/
864906
protected function validateAndUpdateGroup(string $entityType, ?string $eventId, string $operation, array $data): void
865907
{
866908
$groupId = $data['id'];
@@ -918,6 +960,11 @@ protected function validateAndUpdateGroup(string $entityType, ?string $eventId,
918960
$this->processPendingEvents('group', $category->getExternalid());
919961
}
920962

963+
/**
964+
* @param array{id: string, name: string, icpc_id?: string|null, formal_name?: string|null, country?: string,
965+
* country_flag?: array{0: array<string, string>}, url?: string, twitter_hashtag?: string,
966+
* twitter_account?: string, location?: array{0: array<string, string>}, logo?: array{0: array<string, string>}} $data
967+
*/
921968
protected function validateAndUpdateOrganization(string $entityType, ?string $eventId, string $operation, array $data): void
922969
{
923970
$organizationId = $data['id'];
@@ -972,6 +1019,9 @@ protected function validateAndUpdateOrganization(string $entityType, ?string $ev
9721019
$this->processPendingEvents('organization', $affiliation->getExternalid());
9731020
}
9741021

1022+
/**
1023+
* @param array{id: string, name: string, time_limit: int, label?: string|null, rgb?: string|null} $data
1024+
*/
9751025
protected function validateAndUpdateProblem(string $entityType, ?string $eventId, string $operation, array $data): void
9761026
{
9771027
if (!$this->warningIfUnsupported($operation, $eventId, $entityType, $data['id'], [EventLogService::ACTION_CREATE, EventLogService::ACTION_UPDATE])) {
@@ -1031,6 +1081,10 @@ protected function validateAndUpdateProblem(string $entityType, ?string $eventId
10311081
$this->processPendingEvents('problem', $problem->getProbid());
10321082
}
10331083

1084+
/**
1085+
* @param array{id: string, name: string, formal_name?: string|null, icpc_id?: string|null, country?: string|null,
1086+
* organization_id?: string|null, group_ids?: string[], display_name?: string|null, country?: string|null} $data
1087+
*/
10341088
protected function validateAndUpdateTeam(string $entityType, ?string $eventId, string $operation, array $data): void
10351089
{
10361090
$teamId = $data['id'];
@@ -1106,6 +1160,8 @@ protected function validateAndUpdateTeam(string $entityType, ?string $eventId, s
11061160
}
11071161

11081162
/**
1163+
* @param array{id: string, text: string, time: string, contest_time: string, from_team_id?: string|null,
1164+
* to_team_id?: string|null, reply_to_id: string|null, problem_id?: string|null} $data
11091165
* @throws NonUniqueResultException
11101166
*/
11111167
protected function importClarification(string $entityType, ?string $eventId, string $operation, array $data): void
@@ -1245,6 +1301,10 @@ protected function importClarification(string $entityType, ?string $eventId, str
12451301
}
12461302

12471303
/**
1304+
* @param array{id: string, language_id: string, problem_id: string, team_id: string,
1305+
* time: string, contest_time: string, entry_point?: string|null,
1306+
* files: array<array{href: string, filename: string, mime?: string}>,
1307+
* reaction?: array<array<string, string>>} $data
12481308
* @throws TransportExceptionInterface
12491309
* @throws DBALException
12501310
* @throws NonUniqueResultException
@@ -1547,6 +1607,8 @@ protected function importSubmission(string $entityType, ?string $eventId, string
15471607
}
15481608

15491609
/**
1610+
* @param array{start_time: string, start_contest_time: string, id: string, submission_id: string,
1611+
* max_run_time?: int|null, end_time?: string|null, output_compile_as_string?: string|null, judgement_type_id?: string|null} $data
15501612
* @throws DBALException
15511613
*/
15521614
protected function importJudgement(string $entityType, ?string $eventId, string $operation, array $data): void
@@ -1668,6 +1730,10 @@ protected function importJudgement(string $entityType, ?string $eventId, string
16681730
$this->processPendingEvents('judgement', $judgement->getExternalid());
16691731
}
16701732

1733+
/**
1734+
* @param array{id: string, judgement_id: string, ordinal: int, judgement_type_id?: string|null,
1735+
* time?: string|null, contest_time?: string|null, run_time?: int|null} $data
1736+
*/
16711737
protected function importRun(string $entityType, ?string $eventId, string $operation, array $data): void
16721738
{
16731739
// Note that we do not emit events for imported runs, as we will generate our own.
@@ -1795,12 +1861,12 @@ protected function processPendingEvents(string $type, string|int $id): void
17951861

17961862
/**
17971863
* @param array{run_time?: float, time?: string, contest_time?: string, ordinal?: int,
1798-
* id: string, judgement_id?: string, judgement_type_id: string|null,
1799-
* max_run_time?: float|null, start_time: string, start_contest_time?: string,
1800-
* end_time?: string|null, end_contest_time?: string|null, submission_id: string,
1801-
* output_compile_as_string: null, language_id?: string, externalid?: null,
1802-
* team_id: string, problem_id?: string, entry_point?: string|null, old_result?: null,
1803-
* files?: array{href: string}} $data
1864+
* id: string, judgement_id?: string, judgement_type_id?: string|null,
1865+
* max_run_time?: float|null, start_time?: string, start_contest_time?: string,
1866+
* end_time?: string|null, end_contest_time?: string|null, submission_id?: string,
1867+
* output_compile_as_string?: string|null, language_id?: string, externalid?: string|null,
1868+
* team_id?: string, problem_id?: string, entry_point?: string|null, old_result?: null,
1869+
* files?: array<array{href: string, filename: string, mime?: string}>} $data
18041870
*/
18051871
protected function addPendingEvent(string $type, string|int $id, string $operation, string $entityType, ?string $eventId, array $data): void
18061872
{
@@ -1894,6 +1960,14 @@ private function markSubmissionAsValidAndRecalcScore(Submission $submission, boo
18941960
$this->scoreboardService->calculateScoreRow($contest, $team, $problem);
18951961
}
18961962

1963+
/**
1964+
* @param array{'affiliation.externalid'?: string|null, 'category.externalid'?: string|null, color?: string|null,
1965+
* country?: string|null, display_name?: string|null, end_time?: string, externalid?: string,
1966+
* freeze_time?: string|null, icpc_id?: string|null, label?: string, name?: string, rgb?: string|null,
1967+
* shortname?: string, sortorder?: int, start_time_enabled?: bool, start_time_string?: string,
1968+
* timelimit?: int, visible?: bool} $values
1969+
* @param array<string, array{0: bool, 1: bool}> $extraDiff
1970+
*/
18971971
private function compareOrCreateValues(
18981972
?string $eventId,
18991973
string $entityType,
@@ -2027,8 +2101,8 @@ protected function removeWarning(string $entityType, ?string $entityId, string $
20272101
* data?: array{run_time?: float, time?: string, contest_time?: string, ordinal?: int,
20282102
* id: string, judgement_id?: string, judgement_type_id: string|null,
20292103
* max_run_time?: float|null, start_time: string, start_contest_time?: string,
2030-
* end_time?: string|null, end_contest_time?: string|null, submission_id: string,
2031-
* output_compile_as_string: null, language_id?: string, externalid?: null,
2104+
* end_time?: string|null, end_contest_time?: string|null, submission_id?: string,
2105+
* output_compile_as_string: null, language_id?: string, externalid?: string|null,
20322106
* team_id: string, problem_id?: string, entry_point?: string|null, old_result?: null,
20332107
* files?: array{href: string}}|mixed[]
20342108
* } $event

webapp/src/Service/StatisticsService.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,9 @@ public function getProblemStats(
401401

402402
/**
403403
* @param Problem[] $problems
404+
* @return array{'numBuckets': int, 'maxBucketSizeCorrect': int, 'maxBucketSizeCorrect': int, 'maxBucketSizeIncorrect': int,
405+
* 'problems': array<array{'correct': array<array{'start': DateTime, 'end': DateTime, 'count': int}>,
406+
* 'incorrect': array<array{'start': DateTime, 'end': DateTime, 'count': int}>}>}
404407
*/
405408
public function getGroupedProblemsStats(
406409
Contest $contest,

0 commit comments

Comments
 (0)