diff options
Diffstat (limited to 'lib/private/AppFramework/Utility/ControllerMethodReflector.php')
-rw-r--r-- | lib/private/AppFramework/Utility/ControllerMethodReflector.php | 70 |
1 files changed, 33 insertions, 37 deletions
diff --git a/lib/private/AppFramework/Utility/ControllerMethodReflector.php b/lib/private/AppFramework/Utility/ControllerMethodReflector.php index b76b3c33c42..679e1788004 100644 --- a/lib/private/AppFramework/Utility/ControllerMethodReflector.php +++ b/lib/private/AppFramework/Utility/ControllerMethodReflector.php @@ -1,35 +1,10 @@ <?php declare(strict_types=1); - /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Bernhard Posselt <dev@bernhard-posselt.com> - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author Joas Schilling <coding@schilljs.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Olivier Paroz <github@oparoz.com> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OC\AppFramework\Utility; @@ -42,6 +17,7 @@ class ControllerMethodReflector implements IControllerMethodReflector { public $annotations = []; private $types = []; private $parameters = []; + private array $ranges = []; /** * @param object $object an object or classname @@ -54,26 +30,38 @@ class ControllerMethodReflector implements IControllerMethodReflector { if ($docs !== false) { // extract everything prefixed by @ and first letter uppercase preg_match_all('/^\h+\*\h+@(?P<annotation>[A-Z]\w+)((?P<parameter>.*))?$/m', $docs, $matches); - foreach ($matches['annotation'] as $key => $annontation) { - $annontation = strtolower($annontation); + foreach ($matches['annotation'] as $key => $annotation) { + $annotation = strtolower($annotation); $annotationValue = $matches['parameter'][$key]; - if (isset($annotationValue[0]) && $annotationValue[0] === '(' && $annotationValue[\strlen($annotationValue) - 1] === ')') { + if (str_starts_with($annotationValue, '(') && str_ends_with($annotationValue, ')')) { $cutString = substr($annotationValue, 1, -1); $cutString = str_replace(' ', '', $cutString); - $splittedArray = explode(',', $cutString); - foreach ($splittedArray as $annotationValues) { + $splitArray = explode(',', $cutString); + foreach ($splitArray as $annotationValues) { [$key, $value] = explode('=', $annotationValues); - $this->annotations[$annontation][$key] = $value; + $this->annotations[$annotation][$key] = $value; } continue; } - $this->annotations[$annontation] = [$annotationValue]; + $this->annotations[$annotation] = [$annotationValue]; } // extract type parameter information preg_match_all('/@param\h+(?P<type>\w+)\h+\$(?P<var>\w+)/', $docs, $matches); $this->types = array_combine($matches['var'], $matches['type']); + preg_match_all('/@psalm-param\h+(\?)?(?P<type>\w+)<(?P<rangeMin>(-?\d+|min)),\h*(?P<rangeMax>(-?\d+|max))>(\|null)?\h+\$(?P<var>\w+)/', $docs, $matches); + foreach ($matches['var'] as $index => $varName) { + if ($matches['type'][$index] !== 'int') { + // only int ranges are possible at the moment + // @see https://psalm.dev/docs/annotating_code/type_syntax/scalar_types + continue; + } + $this->ranges[$varName] = [ + 'min' => $matches['rangeMin'][$index] === 'min' ? PHP_INT_MIN : (int)$matches['rangeMin'][$index], + 'max' => $matches['rangeMax'][$index] === 'max' ? PHP_INT_MAX : (int)$matches['rangeMax'][$index], + ]; + } } foreach ($reflection->getParameters() as $param) { @@ -94,9 +82,9 @@ class ControllerMethodReflector implements IControllerMethodReflector { /** * Inspects the PHPDoc parameters for types * @param string $parameter the parameter whose type comments should be - * parsed + * parsed * @return string|null type in the type parameters (@param int $something) - * would return int or null if not existing + * would return int or null if not existing */ public function getType(string $parameter) { if (array_key_exists($parameter, $this->types)) { @@ -106,6 +94,14 @@ class ControllerMethodReflector implements IControllerMethodReflector { return null; } + public function getRange(string $parameter): ?array { + if (array_key_exists($parameter, $this->ranges)) { + return $this->ranges[$parameter]; + } + + return null; + } + /** * @return array the arguments of the method with key => default value */ |