From e4f2dd18ef6959a13a3ae9885ba6a88f491f4b2c Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sun, 16 Feb 2025 12:39:58 +0300 Subject: [PATCH 1/5] feat: active record generic types --- framework/db/ActiveQuery.php | 33 +++++++++++++++++++++++++++++++-- tests/data/ar/CustomerQuery.php | 1 + 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/framework/db/ActiveQuery.php b/framework/db/ActiveQuery.php index 400918f1c4b..6a7246b5ecd 100644 --- a/framework/db/ActiveQuery.php +++ b/framework/db/ActiveQuery.php @@ -69,6 +69,8 @@ * @author Qiang Xue * @author Carsten Brandt * @since 2.0 + * + * @template T of (ActiveRecord|array) */ class ActiveQuery extends Query implements ActiveQueryInterface { @@ -126,7 +128,9 @@ public function init() * Executes query and returns all results as an array. * @param Connection|null $db the DB connection used to create the DB command. * If null, the DB connection returned by [[modelClass]] will be used. - * @return array|ActiveRecord[] the query results. If the query results in nothing, an empty array will be returned. + * @return T[] the query results. If the query results in nothing, an empty array will be returned. + * @psalm-return T[] + * @phpstan-return T[] */ public function all($db = null) { @@ -295,9 +299,11 @@ private function removeDuplicatedModels($models) * Executes query and returns a single row of result. * @param Connection|null $db the DB connection used to create the DB command. * If `null`, the DB connection returned by [[modelClass]] will be used. - * @return ActiveRecord|array|null a single row of query result. Depending on the setting of [[asArray]], + * @return T|null a single row of query result. Depending on the setting of [[asArray]], * the query result may be either an array or an ActiveRecord object. `null` will be returned * if the query results in nothing. + * @psalm-return T|null + * @phpstan-return T|null */ public function one($db = null) { @@ -310,6 +316,29 @@ public function one($db = null) return null; } + /** + * {@inheritdoc} + * + * @return T[][] + * @psalm-return T[][]|BatchQueryResult + * @phpstan-return T[][]|BatchQueryResult + */ + public function batch($batchSize = 100, $db = null) + { + return parent::batch($batchSize, $db); + } + + /** + * {@inheritdoc} + * @return T[] + * @psalm-return T[]|BatchQueryResult + * @phpstan-return T[]|BatchQueryResult + */ + public function each($batchSize = 100, $db = null) + { + return parent::each($batchSize, $db); + } + /** * Creates a DB command that can be used to execute this query. * @param Connection|null $db the DB connection used to create the DB command. diff --git a/tests/data/ar/CustomerQuery.php b/tests/data/ar/CustomerQuery.php index 55efd4f7c04..ce6677a0cdd 100644 --- a/tests/data/ar/CustomerQuery.php +++ b/tests/data/ar/CustomerQuery.php @@ -11,6 +11,7 @@ /** * CustomerQuery. + * @extends ActiveQuery */ class CustomerQuery extends ActiveQuery { From 230b699cb8b2a3944f27a628a9e03d449f5b47eb Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Sun, 16 Feb 2025 18:53:05 +0300 Subject: [PATCH 2/5] chore: ignore CC --- framework/db/ActiveQuery.php | 3 +++ tests/data/ar/CustomerWithAlias.php | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/framework/db/ActiveQuery.php b/framework/db/ActiveQuery.php index 6a7246b5ecd..481e198595b 100644 --- a/framework/db/ActiveQuery.php +++ b/framework/db/ActiveQuery.php @@ -322,6 +322,7 @@ public function one($db = null) * @return T[][] * @psalm-return T[][]|BatchQueryResult * @phpstan-return T[][]|BatchQueryResult + * @codeCoverageIgnore */ public function batch($batchSize = 100, $db = null) { @@ -330,9 +331,11 @@ public function batch($batchSize = 100, $db = null) /** * {@inheritdoc} + * * @return T[] * @psalm-return T[]|BatchQueryResult * @phpstan-return T[]|BatchQueryResult + * @codeCoverageIgnore */ public function each($batchSize = 100, $db = null) { diff --git a/tests/data/ar/CustomerWithAlias.php b/tests/data/ar/CustomerWithAlias.php index a5a31c5c478..9e56859e747 100644 --- a/tests/data/ar/CustomerWithAlias.php +++ b/tests/data/ar/CustomerWithAlias.php @@ -21,12 +21,12 @@ class CustomerWithAlias extends ActiveRecord public $status2; public $sumTotal; - + public static function tableName() { return 'customer'; } - + /** * {@inheritdoc} * @return CustomerQuery From f92cb85e7a90df1c8b3bfa875609160e46aa180b Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 21 Feb 2025 11:00:39 +0300 Subject: [PATCH 3/5] feat: revert basic phpdoc types --- framework/db/ActiveQuery.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/db/ActiveQuery.php b/framework/db/ActiveQuery.php index 481e198595b..67d48b98b99 100644 --- a/framework/db/ActiveQuery.php +++ b/framework/db/ActiveQuery.php @@ -128,7 +128,7 @@ public function init() * Executes query and returns all results as an array. * @param Connection|null $db the DB connection used to create the DB command. * If null, the DB connection returned by [[modelClass]] will be used. - * @return T[] the query results. If the query results in nothing, an empty array will be returned. + * @return array|ActiveRecord[] the query results. If the query results in nothing, an empty array will be returned. * @psalm-return T[] * @phpstan-return T[] */ @@ -299,7 +299,7 @@ private function removeDuplicatedModels($models) * Executes query and returns a single row of result. * @param Connection|null $db the DB connection used to create the DB command. * If `null`, the DB connection returned by [[modelClass]] will be used. - * @return T|null a single row of query result. Depending on the setting of [[asArray]], + * @return array|ActiveRecord|null a single row of query result. Depending on the setting of [[asArray]], * the query result may be either an array or an ActiveRecord object. `null` will be returned * if the query results in nothing. * @psalm-return T|null @@ -319,7 +319,7 @@ public function one($db = null) /** * {@inheritdoc} * - * @return T[][] + * @return BatchQueryResult * @psalm-return T[][]|BatchQueryResult * @phpstan-return T[][]|BatchQueryResult * @codeCoverageIgnore @@ -332,7 +332,7 @@ public function batch($batchSize = 100, $db = null) /** * {@inheritdoc} * - * @return T[] + * @return BatchQueryResult * @psalm-return T[]|BatchQueryResult * @phpstan-return T[]|BatchQueryResult * @codeCoverageIgnore From eba2df85de509addf0d7a72f523a5d797eae4157 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 21 Feb 2025 11:05:54 +0300 Subject: [PATCH 4/5] feat: type container --- framework/di/Container.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/framework/di/Container.php b/framework/di/Container.php index 4a364f9acff..9661c6ae338 100644 --- a/framework/di/Container.php +++ b/framework/di/Container.php @@ -157,6 +157,13 @@ class Container extends Component * @return object an instance of the requested class. * @throws InvalidConfigException if the class cannot be recognized or correspond to an invalid definition * @throws NotInstantiableException If resolved to an abstract class or an interface (since 2.0.9) + * + * + * @template T of class-string + * @psalm-param class-string|array{class: class-string} $class + * @phpstan-param class-string|array{class: class-string} $class + * @psalm-return T + * @phpstan-return T */ public function get($class, $params = [], $config = []) { @@ -382,7 +389,7 @@ public function getDefinitions() protected function build($class, $params, $config) { /* @var $reflection ReflectionClass */ - list($reflection, $dependencies) = $this->getDependencies($class); + [$reflection, $dependencies] = $this->getDependencies($class); $addDependencies = []; if (isset($config['__construct()'])) { From 2890fb5210bcab46e556db5214b36d632980f198 Mon Sep 17 00:00:00 2001 From: Dmitriy Derepko Date: Fri, 21 Feb 2025 11:07:20 +0300 Subject: [PATCH 5/5] fix: rollback changes --- framework/di/Container.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/di/Container.php b/framework/di/Container.php index 9661c6ae338..817f0b0a23a 100644 --- a/framework/di/Container.php +++ b/framework/di/Container.php @@ -389,7 +389,7 @@ public function getDefinitions() protected function build($class, $params, $config) { /* @var $reflection ReflectionClass */ - [$reflection, $dependencies] = $this->getDependencies($class); + list($reflection, $dependencies) = $this->getDependencies($class); $addDependencies = []; if (isset($config['__construct()'])) {