Skip to content

Commit

Permalink
Annotate arrays for PHPstan to better analyze the code
Browse files Browse the repository at this point in the history
Most is based on dumping the object, others on reading the code.
  • Loading branch information
vmcj committed Feb 5, 2024
1 parent 0a72de8 commit 6b9a37d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 86 deletions.
85 changes: 0 additions & 85 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -265,91 +265,6 @@ parameters:
count: 1
path: webapp/src/Service/BalloonService.php

-
message: "#^Method App\\\\Service\\\\CheckConfigService\\:\\:checkAllExternalIdentifiers\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/CheckConfigService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:apiRelativeUrl\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:getContestStats\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:getDocLinks\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:getProblemsForExecutable\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:getTwigDataForProblemsAction\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:getUnreadClarifications\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:getUpdates\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:internalApiRequest\\(\\) has parameter \\$queryOrPostData with no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:parseMetadata\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:printFile\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\DOMJudgeService\\:\\:setInternalError\\(\\) has parameter \\$disabled with no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/DOMJudgeService.php

-
message: "#^Method App\\\\Service\\\\EventLogService\\:\\:hasAllDependentObjectEvents\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/EventLogService.php

-
message: "#^Method App\\\\Service\\\\EventLogService\\:\\:insertEvent\\(\\) has parameter \\$content with no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/EventLogService.php

-
message: "#^Method App\\\\Service\\\\EventLogService\\:\\:insertEvents\\(\\) has parameter \\$contents with no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/EventLogService.php

-
message: "#^Method App\\\\Service\\\\EventLogService\\:\\:insertEvents\\(\\) has parameter \\$endpointIds with no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/EventLogService.php

-
message: "#^Property App\\\\Service\\\\EventLogService\\:\\:\\$entityToEndpoint type has no value type specified in iterable type array\\.$#"
count: 1
path: webapp/src/Service/EventLogService.php

-
message: "#^Method App\\\\Service\\\\ExternalContestSourceService\\:\\:addOrUpdateWarning\\(\\) has parameter \\$content with no value type specified in iterable type array\\.$#"
count: 1
Expand Down
3 changes: 3 additions & 0 deletions webapp/src/Service/CheckConfigService.php
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,9 @@ public function checkSelfRegistration(): array
'desc' => $desc];
}

/**
* @return array<string, array{caption: string, result: string, desc: string, escape: bool}>
*/
public function checkAllExternalIdentifiers(): array
{
$this->stopwatch->start(__FUNCTION__);
Expand Down
37 changes: 37 additions & 0 deletions webapp/src/Service/DOMJudgeService.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use App\Entity\User;
use App\Utils\FreezeData;
use App\Utils\Utils;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
Expand Down Expand Up @@ -294,6 +295,9 @@ public function clearCookie(
return $response;
}

/**
* @return array<array{'clarid': int, 'body': string}>
*/
public function getUnreadClarifications(): array
{
$user = $this->getUser();
Expand All @@ -315,6 +319,16 @@ public function getUnreadClarifications(): array
return $unreadClarifications;
}

/**
* @return array{clarifications: array<array{clarid: int, body: string}>,
* judgehosts: array<array{hostname: string, polltime: float}>,
* rejudgings: array<array{rejudgingid: int, starttime: string, endtime: string|float}>,
* internal_errors: array<array{errorid: int, description: string}>,
* balloons: array<array{balloonid: int, name: string, location: string|null, pname: string}>,
* shadow_difference_count: int,
* external_contest_source_is_down: bool,
* external_source_warning_count: int}
*/
public function getUpdates(): array
{
$contest = $this->getCurrentContest();
Expand Down Expand Up @@ -540,6 +554,9 @@ public function jsonEncode(mixed $data): string

/**
* Dis- or re-enable what caused an internal error.
*
* @param array{kind: string, probid?: string, hostname?: string, langid?: string,
* execid?: string, testcaseid?: string} $disabled
*/
public function setInternalError(array $disabled, ?Contest $contest, ?bool $enabled): void
{
Expand Down Expand Up @@ -628,6 +645,7 @@ public function setInternalError(array $disabled, ?Contest $contest, ?bool $enab
/**
* Perform an internal API request to the given URL with the given data.
*
* @param array<string, string[]> $queryOrPostData
* @param UploadedFile[] $files
*
* @return mixed|null
Expand Down Expand Up @@ -676,6 +694,9 @@ public function getDomjudgeWebappDir(): string
return $this->params->get('domjudge.webappdir');
}

/**
* @return array{'name': string, 'link'?: string, 'icon'?: string}
*/
public function getDocLinks(): array
{
return $this->params->get('domjudge.doc_links');
Expand Down Expand Up @@ -715,6 +736,7 @@ public function openZipFile(string $filename): ZipArchive
* @param string|null $teamname Teamname of the team this user belongs to, if any
* @param string|null $teamid Teamid of the team this user belongs to, if any
* @param string|null $location Location of the team, if any.
* @return array{0: bool, 1: string}
*/
public function printFile(
string $filename,
Expand Down Expand Up @@ -908,6 +930,7 @@ public function getAttachmentStreamedResponse(ContestProblem $contestProblem, in
/**
* @throws NoResultException
* @throws NonUniqueResultException
* @return array<string, int>
*/
public function getContestStats(Contest $contest): array
{
Expand Down Expand Up @@ -944,6 +967,12 @@ public function getContestStats(Contest $contest): array
}

/**
* @return array{'problems': ContestProblem[], 'samples': string[], 'showLimits': bool,
* 'defaultMemoryLimit': int, 'timeFactorDiffers': bool,
* 'stats': array{'numBuckets': int, 'maxBucketSizeCorrect': int,
* 'maxBucketSizeCorrect': int, 'maxBucketSizeIncorrect': int,
* 'problems': array<array{'correct': array<array{'start': DateTime, 'end': DateTime, 'count': int}>,
* 'incorrect': array<array{'start': DateTime, 'end': DateTime, 'count': int}>}>}}
* @throws NonUniqueResultException
*/
public function getTwigDataForProblemsAction(
Expand Down Expand Up @@ -1311,6 +1340,9 @@ public function getImmutableRunExecutable(ContestProblem $problem): ImmutableExe
return $executable->getImmutableExecutable();
}

/**
* @return Problem[]
*/
private function getProblemsForExecutable(Executable $executable): array
{
$ret = array_merge($executable->getProblemsCompare()->toArray(),
Expand All @@ -1328,6 +1360,8 @@ private function getProblemsForExecutable(Executable $executable): array

/**
* Get the URL to a route relative to the API root
*
* @param array<string, string> $params
*/
public function apiRelativeUrl(string $route, array $params = []): string
{
Expand Down Expand Up @@ -1453,6 +1487,9 @@ public function loadTeam(string $idField, string $teamId, Contest $contest): Tea
return $team;
}

/**
* @return array<string, string>
*/
public function parseMetadata(string $raw_metadata): array
{
// TODO: Reduce duplication with judgedaemon code.
Expand Down
10 changes: 9 additions & 1 deletion webapp/src/Service/EventLogService.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ class EventLogService
],
];

// Entities to endpoints. Will be filled automatically except for special cases.
/**
* Entities to endpoints. Will be filled automatically except for special cases.
* @var array<string, string> $entityToEndpoint
*/
protected array $entityToEndpoint = [
// Special case for contest problems, as they should map to problems.
ContestProblem::class => 'problems',
Expand Down Expand Up @@ -566,6 +569,8 @@ public function addMissingStateEvents(Contest $contest): void
* This method will make sure that the events are all only inserted once,
* even if called simultaneously from different processes.
*
* @param string[] $endpointIds
* @param array<array<string, mixed>> $contents
* @throws NonUniqueResultException
*/
protected function insertEvents(
Expand Down Expand Up @@ -631,6 +636,8 @@ protected function insertEvents(
* This method will make sure that the event is only inserted once,
* even if called simultaneously from different processes.
*
* @param array<string, string|null> $content
*
* @throws NonUniqueResultException
*/
protected function insertEvent(
Expand Down Expand Up @@ -723,6 +730,7 @@ public function initStaticEvents(Contest $contest): void

/**
* Check if all events for dependent objects are present for the given type and data.
* @param array<string, string|int|null|bool|string[]> $data
* @return bool True if and only if all references are present
*/
protected function hasAllDependentObjectEvents(Contest $contest, string $type, array $data): bool
Expand Down

0 comments on commit 6b9a37d

Please sign in to comment.