diff --git a/composer.json b/composer.json
index 179c7261c2e..72e8252f545 100644
--- a/composer.json
+++ b/composer.json
@@ -103,6 +103,7 @@
"vendor/bin/ecs check bin packages src tests --fix",
"bin/clean_trailing_spaces.sh"
],
+ "docs": "@update-docs",
"phpstan": "vendor/bin/phpstan analyse packages src tests",
"update-docs": "bin/rector generate-rector-overview > docs/AllRectorsOverview.md",
"pre-autoload-dump": [
diff --git a/config/level/coding-style.yml b/config/level/coding-style.yml
deleted file mode 100644
index e01188d957b..00000000000
--- a/config/level/coding-style.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-services:
- Rector\CodingStyle\Rector\If_\NullableCompareToNullRector: ~
diff --git a/config/level/coding-style/coding-style.yml b/config/level/coding-style/coding-style.yml
new file mode 100644
index 00000000000..0dd7a9adb4a
--- /dev/null
+++ b/config/level/coding-style/coding-style.yml
@@ -0,0 +1,6 @@
+services:
+ Rector\CodingStyle\Rector\If_\NullableCompareToNullRector: ~
+ Rector\CodingStyle\Rector\ClassConst\CompleteVarDocTypeConstantRector: ~
+ Rector\CodingStyle\Rector\FuncCall\SimpleArrayCallableToStringRector: ~
+ Rector\CodingStyle\Rector\Identical\IdenticalFalseToBooleanNotRector: ~
+ Rector\CodingStyle\Rector\Switch_\BinarySwitchToIfElseRector: ~
diff --git a/docs/AllRectorsOverview.md b/docs/AllRectorsOverview.md
index 7eb349897b4..45fe6f7f0ad 100644
--- a/docs/AllRectorsOverview.md
+++ b/docs/AllRectorsOverview.md
@@ -18,6 +18,7 @@
- [CodeQuality\Return_](#codequalityreturn_)
- [CodeQuality\Stmt](#codequalitystmt)
- [CodeQuality\Ternary](#codequalityternary)
+- [CodingStyle\ClassConst](#codingstyleclassconst)
- [CodingStyle\FuncCall](#codingstylefunccall)
- [CodingStyle\Identical](#codingstyleidentical)
- [CodingStyle\If_](#codingstyleif_)
@@ -411,6 +412,26 @@ Remove unnecessary ternary expressions.
+## CodingStyle\ClassConst
+
+### `CompleteVarDocTypeConstantRector`
+
+- class: `Rector\CodingStyle\Rector\ClassConst\CompleteVarDocTypeConstantRector`
+
+Complete constant `@var` annotations for missing one, yet known.
+
+```diff
+ final class SomeClass
+ {
++ /**
++ * @var int
++ */
+ private const NUMBER = 5;
+ }
+```
+
+
+
## CodingStyle\FuncCall
### `SimpleArrayCallableToStringRector`
@@ -1361,7 +1382,7 @@ Null is no more allowed in get_class()
- class: `Rector\Php\Rector\FuncCall\TrailingCommaArgumentsRector`
-Adds trailing commas to function and methods calls
+Adds trailing commas to function and methods calls
```diff
calling(
@@ -1744,6 +1765,29 @@ Changes reserved "Object" name to "Object" where can be configure
## Php\Property
+### `CompleteVarDocTypePropertyRector`
+
+- class: `Rector\Php\Rector\Property\CompleteVarDocTypePropertyRector`
+
+Complete property `@var` annotations for missing one, yet known.
+
+```diff
+ final class SomeClass
+ {
++ /**
++ * @var EventDispatcher
++ */
+ private $eventDispatcher;
+
+ public function __construct(EventDispatcher $eventDispatcher)
+ {
+ $this->eventDispatcher = $eventDispatcher;
+ }
+ }
+```
+
+
+
### `TypedPropertyRector`
- class: `Rector\Php\Rector\Property\TypedPropertyRector`
diff --git a/packages/CodingStyle/src/Rector/ClassConst/CompleteVarDocTypeConstantRector.php b/packages/CodingStyle/src/Rector/ClassConst/CompleteVarDocTypeConstantRector.php
new file mode 100644
index 00000000000..28c6e3d492f
--- /dev/null
+++ b/packages/CodingStyle/src/Rector/ClassConst/CompleteVarDocTypeConstantRector.php
@@ -0,0 +1,86 @@
+docBlockAnalyzer = $docBlockAnalyzer;
+ $this->nodeToStringTypeResolver = $nodeToStringTypeResolver;
+ }
+
+ public function getDefinition(): RectorDefinition
+ {
+ return new RectorDefinition('Complete constant `@var` annotations for missing one, yet known.', [
+ new CodeSample(
+ <<<'CODE_SAMPLE'
+final class SomeClass
+{
+ private const NUMBER = 5;
+}
+CODE_SAMPLE
+ ,
+ <<<'CODE_SAMPLE'
+final class SomeClass
+{
+ /**
+ * @var int
+ */
+ private const NUMBER = 5;
+}
+CODE_SAMPLE
+ ),
+ ]);
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getNodeTypes(): array
+ {
+ return [ClassConst::class];
+ }
+
+ /**
+ * @param ClassConst $node
+ */
+ public function refactor(Node $node): ?Node
+ {
+ if ($this->docBlockAnalyzer->hasTag($node, 'var')) {
+ return null;
+ }
+
+ // work only with single-constant
+ if (count($node->consts) > 1) {
+ return null;
+ }
+
+ $knownType = $this->nodeToStringTypeResolver->resolver($node->consts[0]->value);
+ if ($knownType === null) {
+ return null;
+ }
+
+ $this->docBlockAnalyzer->addVarTag($node, $knownType);
+
+ return $node;
+ }
+}
diff --git a/packages/CodingStyle/tests/Rector/ClassConst/CompleteVarDocTypeConstantRector/CompleteVarDocTypeConstantRectorTest.php b/packages/CodingStyle/tests/Rector/ClassConst/CompleteVarDocTypeConstantRector/CompleteVarDocTypeConstantRectorTest.php
new file mode 100644
index 00000000000..8959f76094f
--- /dev/null
+++ b/packages/CodingStyle/tests/Rector/ClassConst/CompleteVarDocTypeConstantRector/CompleteVarDocTypeConstantRectorTest.php
@@ -0,0 +1,19 @@
+doTestFiles([__DIR__ . '/Fixture/fixture.php.inc']);
+ }
+
+ protected function getRectorClass(): string
+ {
+ return CompleteVarDocTypeConstantRector::class;
+ }
+}
diff --git a/packages/CodingStyle/tests/Rector/ClassConst/CompleteVarDocTypeConstantRector/Fixture/fixture.php.inc b/packages/CodingStyle/tests/Rector/ClassConst/CompleteVarDocTypeConstantRector/Fixture/fixture.php.inc
new file mode 100644
index 00000000000..d08b6648637
--- /dev/null
+++ b/packages/CodingStyle/tests/Rector/ClassConst/CompleteVarDocTypeConstantRector/Fixture/fixture.php.inc
@@ -0,0 +1,38 @@
+
+-----
+
diff --git a/packages/ContributorTools/templates/packages/_Package_/tests/Rector/_Category_/_Name_/Fixture/fixture.php.inc b/packages/ContributorTools/templates/packages/_Package_/tests/Rector/_Category_/_Name_/Fixture/fixture.php.inc
index cf06cf9154e..e5d90f44cdd 100644
--- a/packages/ContributorTools/templates/packages/_Package_/tests/Rector/_Category_/_Name_/Fixture/fixture.php.inc
+++ b/packages/ContributorTools/templates/packages/_Package_/tests/Rector/_Category_/_Name_/Fixture/fixture.php.inc
@@ -1,9 +1,13 @@
-----