Skip to content

Commit 64463e7

Browse files
committed
add rector
1 parent 31952e1 commit 64463e7

129 files changed

Lines changed: 910 additions & 1008 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@
7171
"stan": "@phpstan",
7272
"stan-baseline": "tools/phpstan --generate-baseline",
7373
"stan-setup": "phive install",
74+
"rector-setup": "cp composer.json composer.backup && composer require --dev rector/rector:\"~2.3.1\" && mv composer.backup composer.json",
75+
"rector-check": "vendor/bin/rector process --dry-run",
76+
"rector-fix": "vendor/bin/rector process",
7477
"test": "phpunit",
7578
"test-coverage": "phpunit --coverage-clover=clover.xml"
7679
}

rector.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
use Rector\Caching\ValueObject\Storage\FileCacheStorage;
5+
use Rector\CodeQuality\Rector\Empty_\SimplifyEmptyCheckOnEmptyArrayRector;
6+
use Rector\CodeQuality\Rector\FuncCall\CompactToVariablesRector;
7+
use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector;
8+
use Rector\CodingStyle\Rector\Assign\SplitDoubleAssignRector;
9+
use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector;
10+
use Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector;
11+
use Rector\CodingStyle\Rector\FuncCall\FunctionFirstClassCallableRector;
12+
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
13+
use Rector\CodingStyle\Rector\String_\UseClassKeywordForClassNameResolutionRector;
14+
use Rector\Config\RectorConfig;
15+
use Rector\DeadCode\Rector\ClassMethod\RemoveUselessReturnTagRector;
16+
use Rector\EarlyReturn\Rector\If_\ChangeOrIfContinueToMultiContinueRector;
17+
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
18+
use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
19+
use Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector;
20+
use Rector\Php80\Rector\Class_\StringableForToStringRector;
21+
use Rector\Set\ValueObject\SetList;
22+
use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector;
23+
use Rector\TypeDeclaration\Rector\ClassMethod\ParamTypeByMethodCallTypeRector;
24+
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictFluentReturnRector;
25+
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector;
26+
use Rector\TypeDeclaration\Rector\Function_\AddFunctionVoidReturnTypeWhereNoReturnRector;
27+
28+
$cacheDir = getenv('RECTOR_CACHE_DIR') ?: sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'rector';
29+
30+
return RectorConfig::configure()
31+
->withPaths([
32+
__DIR__ . '/src',
33+
__DIR__ . '/tests',
34+
])
35+
36+
->withCache(
37+
cacheClass: FileCacheStorage::class,
38+
cacheDirectory: $cacheDir,
39+
)
40+
41+
->withPhpSets()
42+
->withAttributesSets()
43+
44+
->withSets([
45+
SetList::CODE_QUALITY,
46+
SetList::CODING_STYLE,
47+
SetList::DEAD_CODE,
48+
SetList::EARLY_RETURN,
49+
SetList::INSTANCEOF,
50+
SetList::TYPE_DECLARATION,
51+
])
52+
53+
->withSkip([
54+
__DIR__ . '/tests/comparisons',
55+
__DIR__ . '/tests/test_app',
56+
57+
ClassPropertyAssignToConstructorPromotionRector::class,
58+
CatchExceptionNameMatchingTypeRector::class,
59+
ClosureToArrowFunctionRector::class,
60+
RemoveUselessReturnTagRector::class,
61+
ReturnTypeFromStrictFluentReturnRector::class,
62+
NewlineAfterStatementRector::class,
63+
StringClassNameToClassConstantRector::class,
64+
ReturnTypeFromStrictTypedCallRector::class,
65+
ParamTypeByMethodCallTypeRector::class,
66+
AddFunctionVoidReturnTypeWhereNoReturnRector::class,
67+
StringableForToStringRector::class,
68+
CompactToVariablesRector::class,
69+
SplitDoubleAssignRector::class,
70+
ChangeOrIfContinueToMultiContinueRector::class,
71+
ExplicitBoolCompareRector::class,
72+
NewlineBeforeNewAssignSetRector::class,
73+
SimplifyEmptyCheckOnEmptyArrayRector::class,
74+
DisallowedEmptyRuleFixerRector::class,
75+
76+
// these causes problems with the testsuite
77+
UseClassKeywordForClassNameResolutionRector::class,
78+
FunctionFirstClassCallableRector::class,
79+
]);

src/BakePlugin.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,11 @@ class BakePlugin extends BasePlugin
3434
{
3535
/**
3636
* Plugin name.
37-
*
38-
* @var string|null
3937
*/
4038
protected ?string $name = 'Bake';
4139

4240
/**
4341
* Load routes or not
44-
*
45-
* @var bool
4642
*/
4743
protected bool $routesEnabled = false;
4844

@@ -95,13 +91,13 @@ protected function discoverCommands(CommandCollection $commands): CommandCollect
9591
$pluginPath = $plugin->getClassPath();
9692

9793
$found = $this->findInPath($namespace, $pluginPath);
98-
if (count($found)) {
94+
if ($found !== []) {
9995
$commands->addMany($found);
10096
}
10197
}
10298

10399
$found = $this->findInPath(Configure::read('App.namespace'), APP);
104-
if (count($found)) {
100+
if ($found !== []) {
105101
$commands->addMany($found);
106102
}
107103

src/CodeGen/ClassBuilder.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818

1919
class ClassBuilder
2020
{
21-
/**
22-
* @var \Bake\CodeGen\ParsedClass|null
23-
*/
2421
protected ?ParsedClass $parsedClass;
2522

2623
/**
@@ -50,7 +47,7 @@ public function getImplements(array $generated = []): array
5047
*/
5148
public function getUserConstants(array $generated = []): array
5249
{
53-
if ($this->parsedClass === null) {
50+
if (!$this->parsedClass instanceof ParsedClass) {
5451
return [];
5552
}
5653

@@ -65,7 +62,7 @@ public function getUserConstants(array $generated = []): array
6562
*/
6663
public function getUserProperties(array $generated = []): array
6764
{
68-
if ($this->parsedClass === null) {
65+
if (!$this->parsedClass instanceof ParsedClass) {
6966
return [];
7067
}
7168

@@ -80,7 +77,7 @@ public function getUserProperties(array $generated = []): array
8077
*/
8178
public function getUserFunctions(array $generated = []): array
8279
{
83-
if ($this->parsedClass === null) {
80+
if (!$this->parsedClass instanceof ParsedClass) {
8481
return [];
8582
}
8683

src/CodeGen/CodeParser.php

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
use PhpParser\Error;
2020
use PhpParser\Node;
21+
use PhpParser\Node\Identifier;
22+
use PhpParser\Node\Name;
2123
use PhpParser\Node\Stmt\Class_;
2224
use PhpParser\Node\Stmt\GroupUse;
2325
use PhpParser\Node\Stmt\Namespace_;
@@ -41,24 +43,12 @@ class CodeParser extends NodeVisitorAbstract
4143
*/
4244
protected const INDENT = ' ';
4345

44-
/**
45-
* @var \PhpParser\Parser
46-
*/
4746
protected Parser $parser;
4847

49-
/**
50-
* @var \PhpParser\NodeTraverser
51-
*/
5248
protected NodeTraverser $traverser;
5349

54-
/**
55-
* @var string
56-
*/
5750
protected string $fileText = '';
5851

59-
/**
60-
* @var array
61-
*/
6252
protected array $parsed = [];
6353

6454
/**
@@ -204,7 +194,7 @@ public function enterNode(Node $node)
204194
$methods[$name] = $this->getNodeCode($method);
205195
}
206196

207-
$implements = array_map(function ($name) {
197+
$implements = array_map(function (Name $name): string {
208198
return (string)$name;
209199
}, $node->implements);
210200

@@ -237,9 +227,8 @@ protected function getNodeCode(NodeAbstract $node): string
237227

238228
$startPos = $node->getStartFilePos();
239229
$endPos = $node->getEndFilePos();
240-
$code .= static::INDENT . substr($this->fileText, $startPos, $endPos - $startPos + 1);
241230

242-
return $code;
231+
return $code . static::INDENT . substr($this->fileText, $startPos, $endPos - $startPos + 1);
243232
}
244233

245234
/**
@@ -255,13 +244,9 @@ protected function normalizeUse(UseItem $use, ?string $prefix = null): array
255244
}
256245

257246
$alias = $use->alias;
258-
if (!$alias) {
247+
if (!$alias instanceof Identifier) {
259248
$last = strrpos($name, '\\', -1);
260-
if ($last !== false) {
261-
$alias = substr($name, strrpos($name, '\\', -1) + 1);
262-
} else {
263-
$alias = $name;
264-
}
249+
$alias = $last !== false ? substr($name, strrpos($name, '\\', -1) + 1) : $name;
265250
}
266251

267252
return [(string)$alias, $name];

src/CodeGen/ColumnTypeExtractor.php

Lines changed: 31 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,13 @@
3434
*/
3535
class ColumnTypeExtractor extends NodeVisitorAbstract
3636
{
37-
/**
38-
* @var \PhpParser\Parser
39-
*/
4037
protected Parser $parser;
4138

4239
/**
4340
* @var array<string, string>
4441
*/
4542
protected array $columnTypes = [];
4643

47-
/**
48-
* @var bool
49-
*/
5044
protected bool $inInitialize = false;
5145

5246
/**
@@ -80,7 +74,7 @@ public function extract(string $code): array
8074
$traverser = new NodeTraverser();
8175
$traverser->addVisitor($this);
8276
$traverser->traverse($ast);
83-
} catch (Exception $e) {
77+
} catch (Exception) {
8478
// If parsing fails, return empty array
8579
return [];
8680
}
@@ -136,37 +130,25 @@ public function leaveNode(Node $node)
136130
protected function processMethodCall(MethodCall $methodCall): void
137131
{
138132
// Check if this is a setColumnType call
139-
if ($methodCall->name instanceof Node\Identifier && $methodCall->name->name === 'setColumnType') {
140-
// Check if it's called on getSchema()
141-
if (
142-
$methodCall->var instanceof MethodCall &&
143-
$methodCall->var->name instanceof Node\Identifier &&
144-
$methodCall->var->name->name === 'getSchema' &&
145-
$methodCall->var->var instanceof Variable &&
146-
$methodCall->var->var->name === 'this'
147-
) {
148-
// Extract the column name and type expression
149-
if (count($methodCall->args) >= 2) {
150-
$columnArgNode = $methodCall->args[0];
151-
$typeArgNode = $methodCall->args[1];
152-
if (!$columnArgNode instanceof Node\Arg || !$typeArgNode instanceof Node\Arg) {
153-
return;
154-
}
155-
$columnArg = $columnArgNode->value;
156-
$typeArg = $typeArgNode->value;
157-
158-
// Get column name
159-
$columnName = $this->getStringValue($columnArg);
160-
if ($columnName === null) {
161-
return;
162-
}
163-
164-
// Get the type expression as a string
165-
$typeExpression = $this->getTypeExpression($typeArg);
166-
if ($typeExpression !== null) {
167-
$this->columnTypes[$columnName] = $typeExpression;
168-
}
169-
}
133+
// Check if it's called on getSchema()
134+
// Extract the column name and type expression
135+
if ($methodCall->name instanceof Node\Identifier && $methodCall->name->name === 'setColumnType' && ($methodCall->var instanceof MethodCall && $methodCall->var->name instanceof Node\Identifier && $methodCall->var->name->name === 'getSchema' && $methodCall->var->var instanceof Variable && $methodCall->var->var->name === 'this') && count($methodCall->args) >= 2) {
136+
$columnArgNode = $methodCall->args[0];
137+
$typeArgNode = $methodCall->args[1];
138+
if (!$columnArgNode instanceof Node\Arg || !$typeArgNode instanceof Node\Arg) {
139+
return;
140+
}
141+
$columnArg = $columnArgNode->value;
142+
$typeArg = $typeArgNode->value;
143+
// Get column name
144+
$columnName = $this->getStringValue($columnArg);
145+
if ($columnName === null) {
146+
return;
147+
}
148+
// Get the type expression as a string
149+
$typeExpression = $this->getTypeExpression($typeArg);
150+
if ($typeExpression !== null) {
151+
$this->columnTypes[$columnName] = $typeExpression;
170152
}
171153
}
172154
}
@@ -204,25 +186,17 @@ protected function getTypeExpression(Node $node): ?string
204186
$methodName = $node->name->name;
205187

206188
// Handle EnumType::from() calls
207-
if ($className === 'EnumType' || str_ends_with($className, '\\EnumType')) {
208-
if ($methodName === 'from' && count($node->args) > 0) {
209-
// Extract the enum class name
210-
$argNode = $node->args[0];
211-
if (!$argNode instanceof Node\Arg) {
212-
return null;
213-
}
214-
$arg = $argNode->value;
215-
if ($arg instanceof Node\Expr\ClassConstFetch) {
216-
if (
217-
$arg->class instanceof Node\Name &&
218-
$arg->name instanceof Node\Identifier &&
219-
$arg->name->name === 'class'
220-
) {
221-
$enumClass = $arg->class->toString();
222-
// Return the full EnumType::from() expression
223-
return 'EnumType::from(' . $enumClass . '::class)';
224-
}
225-
}
189+
if (($className === 'EnumType' || str_ends_with($className, '\\EnumType')) && ($methodName === 'from' && $node->args !== [])) {
190+
// Extract the enum class name
191+
$argNode = $node->args[0];
192+
if (!$argNode instanceof Node\Arg) {
193+
return null;
194+
}
195+
$arg = $argNode->value;
196+
if ($arg instanceof Node\Expr\ClassConstFetch && ($arg->class instanceof Node\Name && $arg->name instanceof Node\Identifier && $arg->name->name === 'class')) {
197+
$enumClass = $arg->class->toString();
198+
// Return the full EnumType::from() expression
199+
return 'EnumType::from(' . $enumClass . '::class)';
226200
}
227201
}
228202
}

src/CodeGen/FileBuilder.php

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,12 @@
2020

2121
class FileBuilder
2222
{
23-
/**
24-
* @var \Cake\Console\ConsoleIo
25-
*/
2623
protected ConsoleIo $io;
2724

28-
/**
29-
* @var string
30-
*/
3125
protected string $namespace;
3226

33-
/**
34-
* @var \Bake\CodeGen\ParsedFile|null
35-
*/
3627
protected ?ParsedFile $parsedFile;
3728

38-
/**
39-
* @var \Bake\CodeGen\ClassBuilder
40-
*/
4129
protected ClassBuilder $classBuilder;
4230

4331
/**
@@ -47,7 +35,7 @@ class FileBuilder
4735
*/
4836
public function __construct(ConsoleIo $io, string $namespace, ?ParsedFile $parsedFile = null)
4937
{
50-
if ($parsedFile && $parsedFile->namespace !== $namespace) {
38+
if ($parsedFile instanceof ParsedFile && $parsedFile->namespace !== $namespace) {
5139
throw new ParseException(sprintf(
5240
'Existing namespace `%s` does not match expected namespace `%s`, cannot update existing file',
5341
$parsedFile->namespace,

0 commit comments

Comments
 (0)