From 3f29f2883a279f2d086300e7ddcf89e2b6fe9477 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 10 Sep 2024 16:18:25 +0700 Subject: [PATCH 1/2] refactor: enable ClosureReturnTypeRector --- rector.php | 2 ++ system/Database/OCI8/Builder.php | 6 +++--- system/Database/OCI8/PreparedQuery.php | 2 +- system/Database/Postgre/Builder.php | 6 +++--- system/Database/Postgre/PreparedQuery.php | 2 +- system/Database/SQLSRV/Builder.php | 4 ++-- system/Database/SQLite3/Builder.php | 2 +- system/Debug/Toolbar/Collectors/Database.php | 2 +- system/Events/Events.php | 2 +- system/HTTP/ContentSecurityPolicy.php | 2 +- system/HTTP/Negotiate.php | 2 +- system/Helpers/Array/ArrayHelper.php | 2 +- system/Router/Router.php | 2 +- system/View/Parser.php | 2 +- tests/system/Commands/Utilities/NamespacesTest.php | 2 +- tests/system/DataConverter/DataConverterTest.php | 4 ++-- tests/system/Debug/TimerTest.php | 2 +- tests/system/Events/EventsTest.php | 6 +++--- tests/system/Test/FeatureTestTraitTest.php | 2 +- tests/system/Validation/ValidationTest.php | 2 +- tests/system/View/ParserTest.php | 6 +++--- 21 files changed, 32 insertions(+), 30 deletions(-) diff --git a/rector.php b/rector.php index 14a079e0ab04..8fd3ab275345 100644 --- a/rector.php +++ b/rector.php @@ -53,6 +53,7 @@ use Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector; use Rector\TypeDeclaration\Rector\Closure\AddClosureVoidReturnTypeWhereNoReturnRector; +use Rector\TypeDeclaration\Rector\Closure\ClosureReturnTypeRector; use Rector\TypeDeclaration\Rector\Empty_\EmptyOnNullableObjectToInstanceOfRector; use Rector\TypeDeclaration\Rector\Function_\AddFunctionVoidReturnTypeWhereNoReturnRector; use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector; @@ -217,6 +218,7 @@ AddFunctionVoidReturnTypeWhereNoReturnRector::class, AddMethodCallBasedStrictParamTypeRector::class, TypedPropertyFromAssignsRector::class, + ClosureReturnTypeRector::class, ]) ->withConfiguredRule(StringClassNameToClassConstantRector::class, [ // keep '\\' prefix string on string '\Foo\Bar' diff --git a/system/Database/OCI8/Builder.php b/system/Database/OCI8/Builder.php index 4423a5243a81..24a6bb53b07c 100644 --- a/system/Database/OCI8/Builder.php +++ b/system/Database/OCI8/Builder.php @@ -109,12 +109,12 @@ protected function _replace(string $table, array $keys, array $values): string { $fieldNames = array_map(static fn ($columnName) => trim($columnName, '"'), $keys); - $uniqueIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames) { + $uniqueIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool { $hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields); return ($index->type === 'PRIMARY') && $hasAllFields; }); - $replaceableFields = array_filter($keys, static function ($columnName) use ($uniqueIndexes) { + $replaceableFields = array_filter($keys, static function ($columnName) use ($uniqueIndexes): bool { foreach ($uniqueIndexes as $index) { if (in_array(trim($columnName, '"'), $index->fields, true)) { return false; @@ -344,7 +344,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri if (empty($constraints)) { $fieldNames = array_map(static fn ($columnName) => trim($columnName, '"'), $keys); - $uniqueIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames) { + $uniqueIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool { $hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields); return ($index->type === 'PRIMARY' || $index->type === 'UNIQUE') && $hasAllFields; diff --git a/system/Database/OCI8/PreparedQuery.php b/system/Database/OCI8/PreparedQuery.php index c267f8061377..feffc3be50b5 100644 --- a/system/Database/OCI8/PreparedQuery.php +++ b/system/Database/OCI8/PreparedQuery.php @@ -113,7 +113,7 @@ public function parameterize(string $sql): string // Track our current value $count = 0; - return preg_replace_callback('/\?/', static function ($matches) use (&$count) { + return preg_replace_callback('/\?/', static function ($matches) use (&$count): string { return ':' . ($count++); }, $sql); } diff --git a/system/Database/Postgre/Builder.php b/system/Database/Postgre/Builder.php index 0d2dce0957ae..12845a0e4f54 100644 --- a/system/Database/Postgre/Builder.php +++ b/system/Database/Postgre/Builder.php @@ -368,7 +368,7 @@ protected function _updateBatch(string $table, array $keys, array $values): stri $sql .= 'WHERE ' . implode( ' AND ', array_map( - static function ($key, $value) use ($table, $alias, $that) { + static function ($key, $value) use ($table, $alias, $that): string|RawSql { if ($value instanceof RawSql && is_string($key)) { return $table . '.' . $key . ' = ' . $value; } @@ -463,7 +463,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri $constraints = $this->QBOptions['constraints'] ?? []; if (empty($constraints)) { - $allIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames) { + $allIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool { $hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields); return ($index->type === 'UNIQUE' || $index->type === 'PRIMARY') && $hasAllFields; @@ -575,7 +575,7 @@ protected function _deleteBatch(string $table, array $keys, array $values): stri $sql .= 'WHERE ' . implode( ' AND ', array_map( - static function ($key, $value) use ($table, $alias, $that) { + static function ($key, $value) use ($table, $alias, $that): RawSql|string { if ($value instanceof RawSql) { return $value; } diff --git a/system/Database/Postgre/PreparedQuery.php b/system/Database/Postgre/PreparedQuery.php index fbea6ac14f3a..33a6c8044c7d 100644 --- a/system/Database/Postgre/PreparedQuery.php +++ b/system/Database/Postgre/PreparedQuery.php @@ -119,7 +119,7 @@ public function parameterize(string $sql): string // Track our current value $count = 0; - return preg_replace_callback('/\?/', static function () use (&$count) { + return preg_replace_callback('/\?/', static function () use (&$count): string { $count++; return "\${$count}"; diff --git a/system/Database/SQLSRV/Builder.php b/system/Database/SQLSRV/Builder.php index a6d0b8e85ccd..fcc0b170084f 100644 --- a/system/Database/SQLSRV/Builder.php +++ b/system/Database/SQLSRV/Builder.php @@ -699,7 +699,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri if (empty($constraints)) { $tableIndexes = $this->db->getIndexData($table); - $uniqueIndexes = array_filter($tableIndexes, static function ($index) use ($fieldNames) { + $uniqueIndexes = array_filter($tableIndexes, static function ($index) use ($fieldNames): bool { $hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields); return $index->type === 'PRIMARY' && $hasAllFields; @@ -707,7 +707,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri // if no primary found then look for unique - since indexes have no order if ($uniqueIndexes === []) { - $uniqueIndexes = array_filter($tableIndexes, static function ($index) use ($fieldNames) { + $uniqueIndexes = array_filter($tableIndexes, static function ($index) use ($fieldNames): bool { $hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields); return $index->type === 'UNIQUE' && $hasAllFields; diff --git a/system/Database/SQLite3/Builder.php b/system/Database/SQLite3/Builder.php index a59270bbc0de..15fc2529aa0d 100644 --- a/system/Database/SQLite3/Builder.php +++ b/system/Database/SQLite3/Builder.php @@ -145,7 +145,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri if (empty($constraints)) { $fieldNames = array_map(static fn ($columnName) => trim($columnName, '`'), $keys); - $allIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames) { + $allIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool { $hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields); return ($index->type === 'PRIMARY' || $index->type === 'UNIQUE') && $hasAllFields; diff --git a/system/Debug/Toolbar/Collectors/Database.php b/system/Debug/Toolbar/Collectors/Database.php index ee9f829b05b8..1a923a35516b 100644 --- a/system/Debug/Toolbar/Collectors/Database.php +++ b/system/Debug/Toolbar/Collectors/Database.php @@ -148,7 +148,7 @@ protected function formatTimelineData(): array public function display(): array { $data = []; - $data['queries'] = array_map(static function (array $query) { + $data['queries'] = array_map(static function (array $query): array { $isDuplicate = $query['duplicate'] === true; $firstNonSystemLine = ''; diff --git a/system/Events/Events.php b/system/Events/Events.php index a06bd7903e69..61b7f5c3b457 100644 --- a/system/Events/Events.php +++ b/system/Events/Events.php @@ -84,7 +84,7 @@ public static function initialize() $files = service('locator')->search('Config/Events.php'); } - $files = array_filter(array_map(static function (string $file) { + $files = array_filter(array_map(static function (string $file): string|false { if (is_file($file)) { return realpath($file) ?: $file; } diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php index 7582bc467733..d0dda0ad5752 100644 --- a/system/HTTP/ContentSecurityPolicy.php +++ b/system/HTTP/ContentSecurityPolicy.php @@ -713,7 +713,7 @@ protected function generateNonces(ResponseInterface $response) $pattern = '/(' . preg_quote($this->styleNonceTag, '/') . '|' . preg_quote($this->scriptNonceTag, '/') . ')/'; - $body = preg_replace_callback($pattern, function ($match) { + $body = preg_replace_callback($pattern, function ($match): string { $nonce = $match[0] === $this->styleNonceTag ? $this->getStyleNonce() : $this->getScriptNonce(); return "nonce=\"{$nonce}\""; diff --git a/system/HTTP/Negotiate.php b/system/HTTP/Negotiate.php index 67a03a38014d..4f218347738d 100644 --- a/system/HTTP/Negotiate.php +++ b/system/HTTP/Negotiate.php @@ -233,7 +233,7 @@ public function parseHeader(string $header): array } // Sort to get the highest results first - usort($results, static function ($a, $b) { + usort($results, static function ($a, $b): int { if ($a['q'] === $b['q']) { $aAst = substr_count($a['value'], '*'); $bAst = substr_count($b['value'], '*'); diff --git a/system/Helpers/Array/ArrayHelper.php b/system/Helpers/Array/ArrayHelper.php index 76b8e8aedfbe..4bbd34427fa1 100644 --- a/system/Helpers/Array/ArrayHelper.php +++ b/system/Helpers/Array/ArrayHelper.php @@ -307,7 +307,7 @@ public static function recursiveCount(array $array, int $counter = 0): int */ public static function sortValuesByNatural(array &$array, $sortByIndex = null): bool { - return usort($array, static function ($currentValue, $nextValue) use ($sortByIndex) { + return usort($array, static function ($currentValue, $nextValue) use ($sortByIndex): int { if ($sortByIndex !== null) { return strnatcmp((string) $currentValue[$sortByIndex], (string) $nextValue[$sortByIndex]); } diff --git a/system/Router/Router.php b/system/Router/Router.php index d60313f6c032..2bb050de30ae 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -433,7 +433,7 @@ protected function checkRoutes(string $uri): bool // Is this route supposed to redirect to another? if ($this->collection->isRedirect($routeKey)) { // replacing matched route groups with references: post/([0-9]+) -> post/$1 - $redirectTo = preg_replace_callback('/(\([^\(]+\))/', static function () { + $redirectTo = preg_replace_callback('/(\([^\(]+\))/', static function (): string { static $i = 1; return '$' . $i++; diff --git a/system/View/Parser.php b/system/View/Parser.php index bbeb00f757c0..6600b0178369 100644 --- a/system/View/Parser.php +++ b/system/View/Parser.php @@ -534,7 +534,7 @@ protected function replaceSingle($pattern, $content, $template, bool $escape = f $content = (string) $content; // Replace the content in the template - return preg_replace_callback($pattern, function ($matches) use ($content, $escape) { + return preg_replace_callback($pattern, function ($matches) use ($content, $escape): string { // Check for {! !} syntax to not escape this one. if ( str_starts_with($matches[0], $this->leftDelimiter . '!') diff --git a/tests/system/Commands/Utilities/NamespacesTest.php b/tests/system/Commands/Utilities/NamespacesTest.php index c32d9280aef4..ffdfa0ddcf8d 100644 --- a/tests/system/Commands/Utilities/NamespacesTest.php +++ b/tests/system/Commands/Utilities/NamespacesTest.php @@ -42,7 +42,7 @@ protected function tearDown(): void */ protected function getBuffer() { - return preg_replace_callback('/(\|\s*[^|]+\s*\|\s*)(.*?)(\s*\|\s*[^|]+\s*\|)/', static function (array $matches) { + return preg_replace_callback('/(\|\s*[^|]+\s*\|\s*)(.*?)(\s*\|\s*[^|]+\s*\|)/', static function (array $matches): string { $matches[2] = str_replace(DIRECTORY_SEPARATOR, '/', $matches[2]); return $matches[1] . $matches[2] . $matches[3]; diff --git a/tests/system/DataConverter/DataConverterTest.php b/tests/system/DataConverter/DataConverterTest.php index 6592f4d801c6..c8975fc114fd 100644 --- a/tests/system/DataConverter/DataConverterTest.php +++ b/tests/system/DataConverter/DataConverterTest.php @@ -570,7 +570,7 @@ public function testReconstructObjectWithClosure(): void 'created_at' => 'datetime', 'updated_at' => 'datetime', ]; - $reconstructor = static function ($array) { + $reconstructor = static function ($array): User { $user = new User(); $user->fill($array); @@ -667,7 +667,7 @@ public function testExtractWithClosure(): void 'created_at' => 'datetime', 'updated_at' => 'datetime', ]; - $extractor = static function ($obj) { + $extractor = static function ($obj): array { $array['id'] = $obj->id; $array['name'] = $obj->name; $array['created_at'] = $obj->created_at; diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index eb3cb243b398..09bf0d535bee 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -144,7 +144,7 @@ public function testRecordFunctionNoReturn(): void public function testRecordFunctionWithReturn(): void { $timer = new Timer(); - $returnValue = $timer->record('longjohn', static function () { + $returnValue = $timer->record('longjohn', static function (): string { usleep(100000); return 'test'; diff --git a/tests/system/Events/EventsTest.php b/tests/system/Events/EventsTest.php index e761c7dff958..db975aaa1825 100644 --- a/tests/system/Events/EventsTest.php +++ b/tests/system/Events/EventsTest.php @@ -121,7 +121,7 @@ public function testCancelEvent(): void // This should cancel the flow of events, and leave // $result = 1. - Events::on('foo', static function ($arg) use (&$result) { + Events::on('foo', static function ($arg) use (&$result): bool { $result = 1; return false; @@ -138,14 +138,14 @@ public function testPriority(): void { $result = 0; - Events::on('foo', static function () use (&$result) { + Events::on('foo', static function () use (&$result): bool { $result = 1; return false; }, EVENT_PRIORITY_NORMAL); // Since this has a higher priority, it will // run first. - Events::on('foo', static function () use (&$result) { + Events::on('foo', static function () use (&$result): bool { $result = 2; return false; diff --git a/tests/system/Test/FeatureTestTraitTest.php b/tests/system/Test/FeatureTestTraitTest.php index 4fd921d6e9a6..be3d590bd15a 100644 --- a/tests/system/Test/FeatureTestTraitTest.php +++ b/tests/system/Test/FeatureTestTraitTest.php @@ -152,7 +152,7 @@ public function testCallValidationTwice(): void [ 'POST', 'section/create', - static function () { + static function (): string { $validation = Services::validation(); $validation->setRule('title', 'title', 'required|min_length[3]'); diff --git a/tests/system/Validation/ValidationTest.php b/tests/system/Validation/ValidationTest.php index 00360f368e66..13991dc45916 100644 --- a/tests/system/Validation/ValidationTest.php +++ b/tests/system/Validation/ValidationTest.php @@ -311,7 +311,7 @@ public function testClosureRuleWithParamError(): void $this->validation->setRules([ 'foo' => [ 'required', - static function ($value, $data, &$error, $field) { + static function ($value, $data, &$error, $field): bool { if ($value !== 'abc') { $error = 'The ' . $field . ' value is not "abc"'; diff --git a/tests/system/View/ParserTest.php b/tests/system/View/ParserTest.php index 0cce9f722ebf..9a9f1fd8d0ac 100644 --- a/tests/system/View/ParserTest.php +++ b/tests/system/View/ParserTest.php @@ -806,7 +806,7 @@ public function testParserPluginClosure(): void public function testParserPluginParams(): void { - $this->parser->addPlugin('growth', static function ($str, array $params) { + $this->parser->addPlugin('growth', static function ($str, array $params): string { $step = $params['step'] ?? 1; $count = $params['count'] ?? 2; @@ -853,7 +853,7 @@ public function testParserSingleTagWithSingleParams(): void public function testParserSingleTagWithQuotedParams(): void { - $this->parser->addPlugin('count', static function (array $params = []) { + $this->parser->addPlugin('count', static function (array $params = []): string { $out = ''; foreach ($params as $index => $param) { @@ -870,7 +870,7 @@ public function testParserSingleTagWithQuotedParams(): void public function testParserSingleTagWithNamedParams(): void { - $this->parser->addPlugin('read_params', static function (array $params = []) { + $this->parser->addPlugin('read_params', static function (array $params = []): string { $out = ''; foreach ($params as $index => $param) { From 8ecbf0da09c1c23d3dcb3403545017b95b09a0d3 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 10 Sep 2024 16:31:47 +0700 Subject: [PATCH 2/2] Fix cs --- system/Events/Events.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Events/Events.php b/system/Events/Events.php index 61b7f5c3b457..ad8efed62f9e 100644 --- a/system/Events/Events.php +++ b/system/Events/Events.php @@ -84,7 +84,7 @@ public static function initialize() $files = service('locator')->search('Config/Events.php'); } - $files = array_filter(array_map(static function (string $file): string|false { + $files = array_filter(array_map(static function (string $file): false|string { if (is_file($file)) { return realpath($file) ?: $file; }