Compare commits

...

223 Commits
1.0.3 ... main

Author SHA1 Message Date
Tomas Votruba
e1b3f1a772 Updated Rector to commit c237f2792eb6fefe4f72387070121ca089a6fc2e
c237f2792e [DeadCode] Remove param docblock on RemoveUnusedPromotedPropertyRector when exists (#5936)
2024-06-02 02:58:00 +00:00
Tomas Votruba
c5d04be877 Updated Rector to commit 1e4595aad241240ee4ebed817a61c35acc7d48f9
1e4595aad2 [DeadCode] Add missing $hasChanged flag on RemoveUnusedPromotedPropertyRector on only change param flag (#5935)
2024-06-02 02:46:18 +00:00
Tomas Votruba
b5cb9152fe Updated Rector to commit 34250fb2cf4a162a43c37e48da852537ba873b63
34250fb2cf [automated] Apply Coding Standard (#5934)
2024-06-02 00:32:04 +00:00
Tomas Votruba
f010267a7c Updated Rector to commit 6b69971dfc740a58aed918782d02710e42004e9d
6b69971dfc [NodeTypeCorrector] Directly use StringType on Intersection of strings on AccessoryNonEmptyStringTypeCorrector (#5933)
2024-06-01 09:25:16 +00:00
Tomas Votruba
0aec9f98bf Updated Rector to commit 564992f291fd0e546a44b7aa802a52bd2091ebfc
564992f291 [Scope] No need to set Scope on PHPStan VirtualNode on PHPStanNodeScopeResolver (#5932)
2024-05-31 14:36:45 +00:00
Tomas Votruba
7498eeeea2 Updated Rector to commit a3ed07f8c8c0b2f7cbd78ce7711871d31bad3998
a3ed07f8c8 [TypeDeclaration] Do not remove docblock with description on MergeDateTimePropertyTypeDeclarationRector (#5931)
2024-05-31 12:20:27 +00:00
Tomas Votruba
8384715773 Updated Rector to commit a3ed07f8c8c0b2f7cbd78ce7711871d31bad3998
a3ed07f8c8 [TypeDeclaration] Do not remove docblock with description on MergeDateTimePropertyTypeDeclarationRector (#5931)
2024-05-30 15:01:50 +00:00
Tomas Votruba
2f4d37d623 Updated Rector to commit b2d1c9d496c3d1b08cfb309faa7e9cbb263db1aa
b2d1c9d496 [TypeDeclaration] Handle double declare(strict_types=1) addition on DeclareStrictTypesRector + IncreaseDeclareStrictTypesRector (#5928)
2024-05-30 14:48:33 +00:00
Tomas Votruba
59fdd48d61 Updated Rector to commit a11a1822149d1a219ddcb84a130503f17faea02c
a11a182214 [Php71] Skip call abstract method on RemoveExtraParametersRector (#5930)
2024-05-30 14:29:32 +00:00
Tomas Votruba
42e9685318 Updated Rector to commit 3090229c9059eb2cc926309d106a5b712b4a3533
3090229c90 [Php81] Skip private method from instantiated class on FirstClassCallableRector (#5929)
2024-05-30 14:16:06 +00:00
Tomas Votruba
600218d107 Updated Rector to commit e03da0434ba9504781928079a63e4d6502b96d85
e03da0434b Exclude StaticClosureRector and StaticArrowFunctionRector from rector-preset (#5927)
2024-05-30 08:12:33 +00:00
Tomas Votruba
7470aa5cdd Updated Rector to commit 2039b67eacda6f438070003568544c3e576bc84c
2039b67eac Exclude IncreaseDeclareStrictTypesRector from rector-preset set as conflict with DeclareStrictTypesRector (#5926)
2024-05-30 07:56:15 +00:00
Tomas Votruba
df92a40a00 Updated Rector to commit 756a45aa1a456e28af0b7ae2b78fecc6f6fee6b1
756a45aa1a [DeadCode] Add RemoveUnusedPublicMethodParameterRector (#5925)
2024-05-30 07:40:25 +00:00
Tomas Votruba
ad8eee4201 Updated Rector to commit 66e57260e66e32c78fac0738d69b49e009b348d6
66e57260e6 [Set] Add new rector-preset set to have opiniated rector rules that can be enabled in rector-src and its extension (#5924)
2024-05-30 07:30:01 +00:00
Tomas Votruba
c9f15d2f2a Updated Rector to commit 30669553df27580da9d1f1367580b784a989808b
30669553df [CI] No need to split into multiple jobs for Rector CI (#5922)
2024-05-29 14:30:34 +00:00
Tomas Votruba
f07c3528a8 Updated Rector to commit eb8a76d2d1a19364f29e0f04b4d635ef751759c8
eb8a76d2d1 [AutoImport] No need RenamedClassesDataCollector usage on UsesClassNameImportSkipVoter (#5921)
2024-05-29 10:02:24 +00:00
Tomas Votruba
2065cb44be Updated Rector to commit f987c4df60c792fabd875cdccd678a5ce2a4eda5
f987c4df60 [DX] Remove UseIncrementAssignRector from coding-style set, as often ignored (#5920)
2024-05-29 07:36:01 +00:00
Tomas Votruba
21e5977c28 Updated Rector to commit 79d1b25263ff589d0eab6751c94234f78fb6d3d4
79d1b25263 [DX] Report rules that registered in withSkip() but never registered in withRules() (#5919)
2024-05-29 07:04:39 +00:00
Tomas Votruba
cf6f6c099f Updated Rector to commit 8470e7dd2de8c3499bb0b72a031d650b57ace06b
8470e7dd2d add note about finalize replacement
2024-05-29 05:38:35 +00:00
Tomas Votruba
2b945fac7b Updated Rector to commit 8c51074a9a121fff732471541b005df99dd71873
8c51074a9a [DX] Soft-deprecate CallableThisArrayToAnonymousFunctionRector, as FirstClassCallableRector  handles the same case better (#5918)
2024-05-29 01:38:37 +00:00
Tomas Votruba
354aa8fd07 Updated Rector to commit 6ad571fc10dfb53adbb5137220dbf2e11fa4d1bb
6ad571fc10 [DX] Ommit post-inc to pre-inc rule from coding-style as too opinionated (#5917)
2024-05-29 01:05:19 +00:00
Tomas Votruba
6fa5131124 Updated Rector to commit 1e88bcf62dec93dca5077b8aefebf7c976fbed52
1e88bcf62d [TypeDeclaration] Add AddTypeFromResourceDocblockRector (#5915)
2024-05-29 00:53:21 +00:00
Tomas Votruba
8a83c1053a Updated Rector to commit 303a1d72497e92464f3cf6f4914f82f4aec8f6a5
303a1d7249 [DX] Ommit static functions/closure from coding-style, as often ignored and depends on personal preference (#5916)
2024-05-29 00:44:25 +00:00
Tomas Votruba
8be3783a6a Updated Rector to commit c625b4cd7feda6cc9e51499d5fcdcd19141227ad
c625b4cd7f [CodingStyle] Use specific mapper FullyQualifiedNodeMapper on NameImporter to get PHPStan type of FullyQualifiedNode (#5914)
2024-05-27 18:32:58 +00:00
Tomas Votruba
b6e05a08f9 Updated Rector to commit c625b4cd7feda6cc9e51499d5fcdcd19141227ad
c625b4cd7f [CodingStyle] Use specific mapper FullyQualifiedNodeMapper on NameImporter to get PHPStan type of FullyQualifiedNode (#5914)
2024-05-26 16:28:54 +00:00
Tomas Votruba
216442a257 Updated Rector to commit 157fe350c770262636872c18fbf5c0a61c6fb126
157fe350c7 Bump phpstan-rules (#5913)
2024-05-26 07:13:37 +00:00
Tomas Votruba
6b071141dc Updated Rector to commit c431eae446a25d1b64573500f40139b20aba2c3a
c431eae446 [PostRector][AutoImport] Handle remove unused import with auto import  enabled on conflict with existing use statement (#5912)
2024-05-25 12:40:53 +00:00
Tomas Votruba
b153174db5 Updated Rector to commit 650ae6a730554c4b7472280e86edbf1b704cce25
650ae6a730 Code quality levels (#5910)
2024-05-25 10:48:12 +00:00
Tomas Votruba
74ec7b2331 Updated Rector to commit 0466bac822c4f35530f75f2081e1955bf06825c7
0466bac822 [PostRector][AutoImport] Allow sub namespace docblock imported on NameImportingPhpDocNodeVisitor (#5911)
2024-05-24 15:09:44 +00:00
Tomas Votruba
5d71d0b09c Updated Rector to commit d6fc9012918faf26cfae30aaad329b8a3c65be75
d6fc901291 [TypeDeclaration] Add TypedPropertyFromJMSSerializerAttributeTypeRector (#5909)
2024-05-24 13:06:38 +00:00
Tomas Votruba
81725974a0 Updated Rector to commit 22d6fc2789f575fff16e76e7c7f963793e11f53b
22d6fc2789 [TypeDeclaration] Add ReturnTypeFromSymfonySerializerRector (#5908)
2024-05-23 13:35:45 +00:00
Tomas Votruba
43c823a1fe Updated Rector to commit b2c9e52bf0776d2475e4d0533267cd11299826f6
b2c9e52bf0 [PostRector] Move instanceof check early before SimpleParameterProvider static call check (#5907)
2024-05-22 02:15:37 +00:00
Tomas Votruba
670c768551 Updated Rector to commit 0621d672f946aabc8bd6c9f70feae32d6a390b9f
0621d672f9  [Php80] Skip mixed doc with description and valid doc on MixedTypeRector  (#5906)
2024-05-21 09:36:37 +00:00
Tomas Votruba
cee60661e8 Updated Rector to commit b8847be9d485ec1b3cde5ee5e099ab3626479eb7
b8847be9d4 [TypeDeclaration] Add ReturnTypeFromReturnCastRector (#5905)
2024-05-20 11:36:06 +00:00
Tomas Votruba
83b82dd7bb Updated Rector to commit d1eb62e703651ec14712439700d6e9b2a60c0763
d1eb62e703 [config] Disable parallel on --debug (#5904)
2024-05-20 06:49:34 +00:00
Tomas Votruba
7a1293fda7 Updated Rector to commit 09d2a599613ac2e174e9d0b825c9da1b8c93b0e4
09d2a59961 few static fixes (#5902)
2024-05-20 02:37:37 +00:00
Tomas Votruba
39908b6b4e Updated Rector to commit f30405751176cf6504a86a8f9e6661c55806b38e
f304057511 Convert time() to Carbon::now()->timestamp (#5901)
2024-05-20 00:15:21 +00:00
Tomas Votruba
fce5bf1293 Updated Rector to commit 0e5343cb24ce394701c5321eb5976573dd8c0afe
0e5343cb24 Few PHPStan fixes (#5900)
2024-05-19 17:46:36 +00:00
Tomas Votruba
9a455bf300 Updated Rector to commit 7d65537690d8d788b595b46f026920b4b17eaaf5
7d65537690 Fix few static errors (#5899)
2024-05-19 17:16:04 +00:00
Tomas Votruba
2210bace5e Updated Rector to commit 196b2d0947a0dbec176209113f52e82ac5673e2b
196b2d0947 Cleanup fixed phpstan errors (#5898)
2024-05-19 16:10:19 +00:00
Tomas Votruba
9f86c20c73 Updated Rector to commit b2613baaf6dbf85c9a784b3baf652925c2f480d2
b2613baaf6 make refactorWithClass() private as it should be
2024-05-19 08:27:29 +00:00
Tomas Votruba
f7ce209bd1 Updated Rector to commit fe31e195e3797b13d296899dda27f30e4980b079
fe31e195e3 [Carbon] Add immutable support to other rules (#5896)
2024-05-19 02:29:27 +00:00
Tomas Votruba
4cadabfe9a Updated Rector to commit 1fd156bddbfece24ad48f83e2a65fb44ccb5392d
1fd156bddb Convert DateTimeImmutable to CarbonImmutable (#5895)
2024-05-19 02:09:52 +00:00
Tomas Votruba
3f56884569 Updated Rector to commit b2ec1f0b413e16760c41707b74c936f7445e13ab
b2ec1f0b41 [Carbon] Skip first class callable on DateTimeMethodCallToCarbonRector (#5893)
2024-05-18 14:48:45 +00:00
Tomas Votruba
22d3d1949d Updated Rector to commit 6ebfa15e733ac340249418057ed3f7615e717ac1
6ebfa15e73 Bump to react/promise 3.1 (#5892)
2024-05-18 13:49:01 +00:00
Tomas Votruba
62a900a1c0 Updated Rector to commit 56d55d0d1e7c064f0859c54d5afc05b5d15d6e9a
56d55d0d1e cs
2024-05-18 13:31:16 +00:00
Tomas Votruba
b98d0a8754 Updated Rector to commit 575921d2bca4a0ef36d55c6fa4ebf1ea01bacc4d
575921d2bc [Carbon] Init set to migrate DateTime to Carbon (#5868)
2024-05-18 13:30:48 +00:00
Tomas Votruba
7ac6f7bf7e Updated Rector to commit 5df95d9a955523a1737442a26f4a412cafc41226
5df95d9a95 Update unit test config to avoid using TypeCombinator::addNull() (#5891)
2024-05-18 12:49:12 +00:00
Tomas Votruba
556509e2dc Rector 1.1.0 2024-05-18 09:40:27 +00:00
Tomas Votruba
dfaafdbd3a Updated Rector to commit 8e4e8823f227290fb6b014c79b48ce211c2376b5
8e4e8823f2 Bump to PHPStan 1.11 (#5883)
2024-05-18 08:00:27 +00:00
Tomas Votruba
dd1dd510f5 Updated Rector to commit 4f301f2335b0fef2934ddaf53471ebd961de1f71
4f301f2335 [Configuration] Add missing LevelSetList::UP_TO_PHP_84 on PhpLevelSetResolver::resolveFromPhpVersion() (#5890)
2024-05-18 07:39:08 +00:00
Tomas Votruba
c6998bfca9 Updated Rector to commit 19863767c63503e19aed359d849fa55bbf3a1df9
19863767c6 [TypeDeclaration] Skip unitialized property on EmptyOnNullableObjectToInstanceOfRector (#5889)
2024-05-17 02:56:57 +00:00
Tomas Votruba
264e16fdae Updated Rector to commit 2deccac9b501bc1aa09ba7e8bfe6271b73e5b8dc
2deccac9b5 [PHPStan] Fix missingType.generics notice on phpstan.neon on PHPStan 1.11 (#5888)
2024-05-16 14:47:37 +00:00
Tomas Votruba
1931c635c0 Updated Rector to commit b938e0797f8c3e30f527d1dabad384e4623140de
b938e0797f [TypeDeclaration] Add test for nullable object usage on AddReturnTypeDeclarationRector (#5887)
2024-05-16 14:03:35 +00:00
Tomas Votruba
df8a377557 Updated Rector to commit 16d1df9be8cdbdf6e5b67f97fa225731ac0c9675
16d1df9be8 [NodeTypeResolver] No need to resolve class name on anonymous classes (#5886)
2024-05-16 13:22:30 +00:00
Tomas Votruba
6372b90b19 Updated Rector to commit db213ee986c942d58e397b3713564349541e8de5
db213ee986 [PHPStan] Handle PHPStan internal ShouldNotHappenException on FamilyRelationsAnalyzer and PHPStanNodeScopeResolver (#5885)
2024-05-16 12:51:40 +00:00
Tomas Votruba
6cf705918e Updated Rector to commit 6a5f6c53f3637b23b4488cab81ec90a0d1bef053
6a5f6c53f3 [TypeDeclaration] Handle crash on interface Mixin on ReturnTypeFromStrictConstantReturnRector (#5884)
2024-05-16 11:45:24 +00:00
Tomas Votruba
3c1e41f006 Updated Rector to commit 6bd2b871c4e9741928fb48df3ca8e899be42be81
6bd2b871c4 [NodeTypeResolver] No need json_decode/json_encode for cache class name collection (#5881)
2024-05-15 02:19:05 +00:00
Tomas Votruba
7d70c5853e Updated Rector to commit 3cf5b1a2b89979dc375701d88608bc03d6a4a7dd
3cf5b1a2b8 [NodeTypeResolver] Clean up resolve cache class name key (#5880)
2024-05-15 02:04:07 +00:00
Tomas Votruba
049336a81a Updated Rector to commit 8ab5e979db19845b9dd3c39bec566830870845dc
8ab5e979db [Performance] Call cached class names collection on FamilyRelationsAnalyzer (#5879)
2024-05-15 01:48:39 +00:00
Tomas Votruba
efe89cff77 Updated Rector to commit 50407e2f2d1c2eb7f67c1f59e8db777e6f0bd081
50407e2f2d [Performance] Ensure call $reflector->reflectAllClasses() once on Worker take 3 (#5878)
2024-05-14 19:26:23 +00:00
Tomas Votruba
89f91b63be Updated Rector to commit a5bf80cb2fdd49d64777cf13250e7205ddd0a3be
a5bf80cb2f [TypeDeclaration] Skip possible array on StrictStringParamConcatRector (#5876)
2024-05-14 13:50:22 +00:00
Tomas Votruba
5dfd1c664c Updated Rector to commit 7182e19c4b0696ee48ff8c828afe47fd34d36d1c
7182e19c4b [TypeDeclaration] Skip array by doc with different assign on ReturnTypeFromStrictNewArrayRector (#5875)
2024-05-14 13:14:40 +00:00
Tomas Votruba
4bcc8bbea0 Updated Rector to commit 8f59d4e23ed974bf9eba52a075ef4d1e2604c80d
8f59d4e23e [Php80] Skip remove non-mixed type doc on MixedTypeRector (#5874)
2024-05-14 08:30:55 +00:00
Tomas Votruba
faba2d1971 Updated Rector to commit 035e7bdb76a5496c65b1c112933e4afe06ddc6f8
035e7bdb76 [NodeTypeResolver] Clean up "this" from NameTypeResolver, as not from Name node (#5873)
2024-05-13 12:23:37 +00:00
Tomas Votruba
c74c9ca74f Updated Rector to commit 419480a0c415b5814065953e0ee8b90a785323a2
419480a0c4 [NodeTypeResolver] Clean up array check on NameTypeResolver (#5872)
2024-05-13 10:38:52 +00:00
Tomas Votruba
b5b172a4b9 Updated Rector to commit eea59bf3b2d52aa7553cfa3d36ea0de69221abe5
eea59bf3b2 Fix "method x was not found in reflection of class" (#5871)
2024-05-13 07:24:53 +00:00
Tomas Votruba
49d837e2a6 Updated Rector to commit e2a184cb16dfe1964feecbe44f7d7cc6130ac010
e2a184cb16 [NodeTypeResolver] Using built int ->isArray()->yes() on ArrayTypeAnalyzer::isArrayType() (#5870)
2024-05-12 15:56:38 +00:00
Tomas Votruba
af81b5db1b Updated Rector to commit b18da7d458c2d240dd50682b31670e134f2b1ed3
b18da7d458 [CodeQuality] Skip on property and class const on CallableThisArrayToAnonymousFunctionRector (#5869)
2024-05-12 07:34:26 +00:00
Tomas Votruba
5ca50de6b7 Updated Rector to commit b18da7d458c2d240dd50682b31670e134f2b1ed3
b18da7d458 [CodeQuality] Skip on property and class const on CallableThisArrayToAnonymousFunctionRector (#5869)
2024-05-11 18:18:48 +00:00
Tomas Votruba
efb3c476c7 Updated Rector to commit ca2988edc997d76a1d7d4b2c6a4f7226478cac7c
ca2988edc9 [CodeQuality] Skip increment variable on else on TernaryFalseExpressionToIfRector (#5867)
2024-05-10 09:40:07 +00:00
Tomas Votruba
73eb63e4f9 Rector 1.0.5 2024-05-10 05:31:15 +00:00
Tomas Votruba
322f3ad55c Updated Rector to commit 48fc55d89350f24521a197c04b5512452a3b50fc
48fc55d893 [StaticTypeMapper] Clean up NameNodeMapper check Scalar and class exists (#5865)
2024-05-10 03:29:37 +00:00
Tomas Votruba
fe891363d5 Updated Rector to commit 558f44d5939be4314d76f4850a34be3590e65bfd
558f44d593 [TypeDeclaration] Skip more detailed type on AddMethodCallBasedStrictParamTypeRector (#5866)
2024-05-10 03:14:36 +00:00
Tomas Votruba
f7723ed647 Updated Rector to commit ef84a1a722c39839de1bcd79e0d3558b3e7d935d
ef84a1a722 [PHPStanStaticTypeMapper] Clean up Intersection type check on UnionTypeMapper (#5864)
2024-05-09 01:12:15 +00:00
Tomas Votruba
ed1310b8dc Updated Rector to commit acb0b5d3ad760e7253fb6f49b4047ec6226384d4
acb0b5d3ad [PHPStanStaticTypeMapper] Clean up UnionTypeMapper: remove unused TypeFactory usage (#5863)
2024-05-08 23:53:57 +00:00
Tomas Votruba
9da012cd97 Updated Rector to commit bb90e0bbafee5e47720d9fda8f7e46fad5bd90a2
bb90e0bbaf [PHPStanStaticTypeMapper] Clean up non-Node type check on UnionTypeMapper (#5862)
2024-05-08 14:07:50 +00:00
Tomas Votruba
dcdff77130 Updated Rector to commit 8371040f72445fda4e96f29783b5de5351524c8a
8371040f72 [TypeDeclaration] Handle array with index assigned on TypedPropertyFromAssignsRector (#5861)
2024-05-08 13:00:27 +00:00
Tomas Votruba
582a864f33 Updated Rector to commit 650dcc6394c6df206772350e525311f8080e5077
650dcc6394 [automated] Apply Coding Standard (#5860)
2024-05-05 00:32:34 +00:00
Tomas Votruba
2dc9d28496 Updated Rector to commit 6649713eb98b016d5503163cd8cbea534ae61f2e
6649713eb9 [automated] Re-Generate Nodes/Rectors Documentation (#5859)
2024-05-05 00:31:57 +00:00
Tomas Votruba
5c55f54e78 Updated Rector to commit 4789b516d98b619f2e04900ab0ae442eb94a5348
4789b516d9 Clean up exclude paths from config-downgrade.php (#5858)
2024-05-05 00:02:51 +00:00
Tomas Votruba
87c26777cb Updated Rector to commit 28e84d24d0f618a8a7e0ff6ea561f1aade554df9
28e84d24d0  [EarlyReturn] Skip with AssignOp on PreparedValueToEarlyReturnRector  (#5857)
2024-05-03 14:46:34 +00:00
Tomas Votruba
19b93eeeab Updated Rector to commit 10558a8d5fb68c0564f995a008b4c666ff932a03
10558a8d5f [NodeTypeResolver] Use existing DefaultReflector::reflectAllClasses() method on DynamicSourceLocatorProvider (#5856)
2024-05-02 19:23:28 +00:00
Tomas Votruba
fb4bddec05 Updated Rector to commit 10558a8d5fb68c0564f995a008b4c666ff932a03
10558a8d5f [NodeTypeResolver] Use existing DefaultReflector::reflectAllClasses() method on DynamicSourceLocatorProvider (#5856)
2024-05-02 11:03:58 +00:00
Tomas Votruba
ee17c27a72 Updated Rector to commit d8f262aa6252740d3a3f17d1f429b7dcf2cc760a
d8f262aa62 [CodeQuality] Skip dynamic second arg or has uppercase second arg on SimplifyStrposLowerRector (#5855)
2024-05-02 09:08:24 +00:00
Tomas Votruba
346b5723b4 Updated Rector to commit 6525345f4d3e594311a7186982087ec17ef8b0ee
6525345f4d [CodeQuality] Fix tautology transformation on identical check on SimplifyTautologyTernaryRector (#5854)
2024-05-02 08:08:51 +00:00
Tomas Votruba
029097acda Updated Rector to commit c7d2ca3f1f2b9153fb05f0ad974b1d4a403be9c3
c7d2ca3f1f Early-return NullSafeMethodCall in NodeNameResolver (#5840)
2024-05-02 07:40:52 +00:00
Tomas Votruba
12c115e6f6 Updated Rector to commit 5193d43b644f9d059d9964ebcc6820181a7bca18
5193d43b64 [NodeTypeResolver] Remove unnecessary loop SourceLocator collection on DynamicSourceLocatorProvider (#5852)
2024-05-02 02:21:56 +00:00
Tomas Votruba
b70df4cb6b Updated Rector to commit 0526417dd6b68191708cff8d636afeeb710c4827
0526417dd6 [Printer] Handle Strip left spaces from opening tags on namespaced PHP + HTML content (#5851)
2024-04-30 22:14:48 +00:00
Tomas Votruba
78e3d54584 Updated Rector to commit 57275efac450b9b0466e9dc934d3c07e2e9a1e43
57275efac4 [TypeDeclarations] Add IncreaseDeclareStrictTypesRector to raise level of declare() coverage (#5849)
2024-04-30 13:26:50 +00:00
Tomas Votruba
c747b603a3 Updated Rector to commit ce1033d8e6434f3111307dd274dec753eb6481b1
ce1033d8e6 Fixes typo in FinalizeTestCaseClassRector.php (#5850)
2024-04-30 12:43:57 +00:00
Tomas Votruba
aff937886f Updated Rector to commit cc4b63fe261a39b55b621e426d87346042412741
cc4b63fe26 CI: take utils/ into account in class-leak (#5847)
2024-04-29 07:35:23 +00:00
Tomas Votruba
343a691722 Updated Rector to commit de41aaf486222ce8a11d645d03ae25cd5678a31f
de41aaf486 Remove "packages" from Rector CI run (#5846)
2024-04-27 02:47:31 +00:00
Tomas Votruba
e9ca0b2469 Updated Rector to commit 9bcded03ea2db7b01183aad2407e3f7490be9531
9bcded03ea [Experiment] Rework child classes detection on DynamicSourceLocatorProvider (#5735)
2024-04-25 08:24:53 +00:00
Tomas Votruba
7141ae6e56 Updated Rector to commit 8281a06bc8432d9d7f8e20842e3961df99a277bc
8281a06bc8 [PHP 7.2] Add error suppres support to each() rule (#5844)
2024-04-24 08:56:31 +00:00
Tomas Votruba
d5e203a6e9 Updated Rector to commit d5069f0fccf649646eeea05b5291c0ac34e511d6
d5069f0fcc [Php83] Handle default native constant on AddTypeToConstRector (#5843)
2024-04-23 12:10:57 +00:00
Tomas Votruba
a3b725126c Updated Rector to commit 775916c6416e68507e846421f04e2cabbfa2d737
775916c641 [Naming] Skip DateTime as individual in name resolver (#5842)
2024-04-23 09:06:40 +00:00
Tomas Votruba
09acbdda13 Updated Rector to commit 6eac87db32eff9308a037fb32ce973ccf905fc92
6eac87db32 Ignore phpdoc type in RecastingRemovalRector (#5841)
2024-04-22 20:26:54 +00:00
Tomas Votruba
fdfd07f062 Updated Rector to commit 6eac87db32eff9308a037fb32ce973ccf905fc92
6eac87db32 Ignore phpdoc type in RecastingRemovalRector (#5841)
2024-04-22 09:35:50 +00:00
Tomas Votruba
c041415e42 Updated Rector to commit 71c6dd929f07d6491847ee9004224441265d0197
71c6dd929f Support NullSafeProperty fetches in unused-code analysis (#5839)
2024-04-21 19:25:07 +00:00
Tomas Votruba
3e1d355024 Updated Rector to commit 4cd2622ccbe9989cdf76a16aa6d282b5ba73adb0
4cd2622ccb Support NullSafeMethod calls in unused-code analysis (#5838)
2024-04-21 19:23:11 +00:00
Tomas Votruba
6cbc8ec497 Updated Rector to commit 068799f59b289bef06b9c1f384df4301b19e726e
068799f59b [Performance] Early skip func call name on ClassRenamer (#5837)
2024-04-21 13:28:31 +00:00
Tomas Votruba
1c323223b2 Updated Rector to commit 068799f59b289bef06b9c1f384df4301b19e726e
068799f59b [Performance] Early skip func call name on ClassRenamer (#5837)
2024-04-21 12:45:15 +00:00
Tomas Votruba
655c2aa498 Updated Rector to commit 068799f59b289bef06b9c1f384df4301b19e726e
068799f59b [Performance] Early skip func call name on ClassRenamer (#5837)
2024-04-21 12:39:04 +00:00
Tomas Votruba
584e892a51 Updated Rector to commit 068799f59b289bef06b9c1f384df4301b19e726e
068799f59b [Performance] Early skip func call name on ClassRenamer (#5837)
2024-04-20 20:05:57 +00:00
Tomas Votruba
b9839a24cb Updated Rector to commit 068799f59b289bef06b9c1f384df4301b19e726e
068799f59b [Performance] Early skip func call name on ClassRenamer (#5837)
2024-04-20 19:29:23 +00:00
Tomas Votruba
1e8aeb3de9 Updated Rector to commit 9ce6af83b6996631fe2a13cca64d25142dc9fb15
9ce6af83b6 [Performance] Early skip NativeFunctionReflection on OptionalParametersAfterRequiredRector (#5836)
2024-04-20 19:24:39 +00:00
Tomas Votruba
8aefc5e967 Updated Rector to commit 1374e15d742f4f36f0bef45db9f8920a589865b3
1374e15d74 [CodeQuality] Add Function_ and FuncCall support on OptionalParametersAfterRequiredRector (#5835)
2024-04-20 11:01:46 +00:00
Tomas Votruba
6db496ec6b Updated Rector to commit b81ef2f28aee9da0861eb67d90d134ec1c537786
b81ef2f28a [Renaming] Skip func call name on RenameClassRector (#5833)
2024-04-19 21:54:58 +00:00
Tomas Votruba
24418026e3 Updated Rector to commit 5e213e66ed72dede6bb43315dbaa2c8d86d449c9
5e213e66ed Revert "Faster FileInfoMatcher (#5830)" (#5831)
2024-04-19 12:41:40 +00:00
Tomas Votruba
e01fd7276e Updated Rector to commit 38b3c20c5b36f1a821d3f38dfef63f547bb1b918
38b3c20c5b Faster FileInfoMatcher (#5830)
2024-04-19 11:48:23 +00:00
Tomas Votruba
61037dab6c Updated Rector to commit 25c1b437061df8d1361f457c603dcd17b10a29c4
25c1b43706 [Php81] Use PHPStan ParametersAcceptor to detect allowed argument types on NullToStrictStringFuncCallArgRector (#5829)
2024-04-18 07:39:11 +00:00
Tomas Votruba
f42da12667 Updated Rector to commit 56e2031ba3eb1886f534e87d6fb533f8b24f6889
56e2031ba3 [CodeQuality] Skip $counter variable exists on ForRepeatedCountToOwnVariableRector (#5828)
2024-04-17 21:03:14 +00:00
Tomas Votruba
83bfbc18b8 Updated Rector to commit d67342e4e23b577a259e2d2af0ed64461db9968b
d67342e4e2 Fix original quotes in PregReplaceEModifierRector (#5827)
2024-04-17 10:04:21 +00:00
Tomas Votruba
b7b08c4396 Updated Rector to commit 7574abd469cbfe569dd47dd9ae9e6aa668a0cf1b
7574abd469 [Php81] Skip mixed type on ArrayDimFetch on NullToStrictStringFuncCallArgRector (#5826)
2024-04-17 09:30:28 +00:00
Tomas Votruba
4f94d24171 Updated Rector to commit 18f482fad0993dbf0b55c628557297610256d87d
18f482fad0 cleanup (#5825)
2024-04-17 09:15:48 +00:00
Tomas Votruba
59f76a0fe3 Updated Rector to commit 33b1f2f39ce2e1f3c42c33749cf65e5c3b780e2c
33b1f2f39c clean up comment autowire on ConditionalTypeMapper (#5824)
2024-04-17 09:12:55 +00:00
Tomas Votruba
ea0464beb9 Updated Rector to commit 8cf4340f3e9ace06e20827147e1065cfd5182efa
8cf4340f3e [TypeDeclaration] Handle crash on @mixin usage on ReturnTypeFromStrictTypedCallRector (#5823)
2024-04-17 08:35:57 +00:00
Tomas Votruba
f3e4fee4bc Updated Rector to commit 2b811afb584aa7a3c569a2ce23d78edbf126d556
2b811afb58 [Php81] Skip always string if else DomElement on NullToStrictStringFuncCallArgRector (#5822)
2024-04-17 07:18:31 +00:00
Tomas Votruba
284531ceed Updated Rector to commit 2b811afb584aa7a3c569a2ce23d78edbf126d556
2b811afb58 [Php81] Skip always string if else DomElement on NullToStrictStringFuncCallArgRector (#5822)
2024-04-15 12:27:37 +00:00
Tomas Votruba
2b9acd03a1 Updated Rector to commit 86eb512e4f78f909856b90bc18e41704b48ee57a
86eb512e4f [automated] Apply Coding Standard (#5821)
2024-04-14 10:00:50 +00:00
Tomas Votruba
885a3f6ed3 Updated Rector to commit 86eb512e4f78f909856b90bc18e41704b48ee57a
86eb512e4f [automated] Apply Coding Standard (#5821)
2024-04-14 08:36:05 +00:00
Tomas Votruba
7d4734bb64 Updated Rector to commit 86eb512e4f78f909856b90bc18e41704b48ee57a
86eb512e4f [automated] Apply Coding Standard (#5821)
2024-04-14 00:31:32 +00:00
Tomas Votruba
7f89a08ca2 Updated Rector to commit 5f212992965828f07b001bf5e3176bcff784bab3
5f21299296 [Util] Register AddCoversClassAttributeRector as by guessing class detection (#5820)
2024-04-13 20:38:29 +00:00
Tomas Votruba
51fa5a731d Updated Rector to commit 3df5a626e5ae8e13aaef8abfc41a136dbf1f367e
3df5a626e5 Clean up SafeLeftTypeBooleanAndOrAnalyzer (#5819)
2024-04-13 07:48:52 +00:00
Tomas Votruba
3a03381bf8 Updated Rector to commit 3df5a626e5ae8e13aaef8abfc41a136dbf1f367e
3df5a626e5 Clean up SafeLeftTypeBooleanAndOrAnalyzer (#5819)
2024-04-12 09:51:06 +00:00
Tomas Votruba
6059061e25 Updated Rector to commit ec59456217e4e2c212c0486cd0ee33221e5ab86c
ec59456217 [DeadCode] Skip $this in trait on RemoveDeadInstanceOfRector (#5818)
2024-04-12 09:47:55 +00:00
Tomas Votruba
f2cac5e2a0 Updated Rector to commit 7d69fc226cab739ec6c47b09bfdd784a24445fe1
7d69fc226c [DeadCode] Skip $this instanceof in Trait on RemoveAlwaysTrueIfConditionRector (#5817)
2024-04-12 09:19:41 +00:00
Tomas Votruba
76a58d63f0 Updated Rector to commit 879a36b44d6b43e4c4d268a3d7e96e0830cac478
879a36b44d [Php81] Skip __invoke() usage from non-class code on FirstClassCallableRector (#5816)
2024-04-11 20:55:59 +00:00
Tomas Votruba
0c2b95ea62 Updated Rector to commit de7b0526ad03b6e2ecc47d28eb8c8e0e5224152a
de7b0526ad [TypeDeclaration] Handle return by array shape type on AddArrowFunctionReturnTypeRector (#5815)
2024-04-10 10:22:01 +00:00
Tomas Votruba
f53efcffe8 Updated Rector to commit 1d2d51e20ce11d0f603e42bd8869c1ab6d2a52cc
1d2d51e20c [Nette] Replace deprecated Json::FORCE_ARRAY and Json::PRETTY on Nette\Utils\Json usage (#5814)
2024-04-09 22:43:38 +00:00
Tomas Votruba
67791a9582 Updated Rector to commit 1d2d51e20ce11d0f603e42bd8869c1ab6d2a52cc
1d2d51e20c [Nette] Replace deprecated Json::FORCE_ARRAY and Json::PRETTY on Nette\Utils\Json usage (#5814)
2024-04-09 21:01:48 +00:00
Tomas Votruba
9427cdb84c Updated Rector to commit 1d2d51e20ce11d0f603e42bd8869c1ab6d2a52cc
1d2d51e20c [Nette] Replace deprecated Json::FORCE_ARRAY and Json::PRETTY on Nette\Utils\Json usage (#5814)
2024-04-09 20:37:51 +00:00
Tomas Votruba
d495dc4fe7 Updated Rector to commit a67952f6d15ef954da70898c58aa10567b51c11e
a67952f6d1 [Php81] Skip on property and class const on FirstClassCallableRector (#5813)
2024-04-08 13:35:12 +00:00
Tomas Votruba
e56fb5adb0 Updated Rector to commit 1bbb3faaed01bd234f8e53564d1686529551e75a
1bbb3faaed [TypeDeclaration] Skip maybe not returned on while on ReturnUnionTypeRector (#5812)
2024-04-08 13:19:12 +00:00
Tomas Votruba
415f0bbf34 Updated Rector to commit 54e2e110d506d6e06e45cb808ce87824306ddd4f
54e2e110d5 [CodeQuality] Skip while(true) always returned on ExplicitReturnNullRector (#5810)
2024-04-08 12:23:14 +00:00
Tomas Votruba
8fba5b95f7 Updated Rector to commit b292010edec6f45b5a48d1f001edce95e05162f3
b292010ede [Performance][TypeDeclaration] Avoid double loop on SilentVoidResolver use NeverFuncCallAnalyzer (#5809)
2024-04-08 09:44:15 +00:00
Tomas Votruba
53fb366ec6 Updated Rector to commit 9939ced45eb3479a1d8b2b9339512398118b92d9
9939ced45e [CodeQuality] Skip never type on default switch on ExplicitReturnNullRector (#5808)
2024-04-08 09:20:15 +00:00
Tomas Votruba
6fb3352189 Updated Rector to commit 690fe892750028e239a01f1b13cd252359994522
690fe89275 [CodeQuality] Skip Always return in try catch with finally on ExplicitReturnNullRector (#5807)
2024-04-07 09:15:50 +00:00
Tomas Votruba
530c01c201 Updated Rector to commit 145b616765b9c534e5ebe4203caa0c0f4dd3b7fc
145b616765 [automated] Apply Coding Standard (#5806)
2024-04-07 00:31:48 +00:00
Tomas Votruba
707e3d8942 Updated Rector to commit 467e971b79acab35e7bb0937166ab2e23bffd245
467e971b79 Make Compatible with phpstan 1.11.x code (#5804)
2024-04-05 22:38:12 +00:00
Tomas Votruba
b8bbd024cd Updated Rector to commit c860b0cd3976acfd4b05d6929f446a7b50454b52
c860b0cd39 Update docs for AddTypeToConstRector (#5803)
2024-04-05 18:05:20 +00:00
Tomas Votruba
6678ca05d4 Updated Rector to commit 4a77565302216f6fde71232600cd175422a00965
4a77565302 ExplicitReturnNullRector should skip never return (#5802)
2024-04-05 18:04:27 +00:00
Tomas Votruba
6e04d0eb08 Rector 1.0.4 2024-04-05 09:01:07 +00:00
Tomas Votruba
d59efe6a88 Updated Rector to commit a16a04d0bc90df11918efd4b7fc117a9e3dcc1c3
a16a04d0bc composer-dependency-analyser: fix dependency issues (#5777)
2024-04-04 14:00:19 +00:00
Tomas Votruba
e004423e08 Updated Rector to commit 8e022d170a2e88d66e12631536f298de8b22d42d
8e022d170a ArgumentRemoverRectorTest: replace symfony\yaml reference with dummy (#5799)
2024-04-03 16:42:28 +00:00
Tomas Votruba
f81fa92915 Updated Rector to commit a43f37190db97fb8807cb08f4e7171a338625387
a43f37190d [CodeQuality] Handle Switch maybe return on ExplicitReturnNullRector (#5801)
2024-04-03 15:10:32 +00:00
Tomas Votruba
d36c8ad1a5 Updated Rector to commit 0348124a5535b99712da4debc136d2e73647b97a
0348124a55 [CodeQuality] Skip Switch_ always returned on ExplicitReturnNullRector (#5800)
2024-04-03 14:37:39 +00:00
Tomas Votruba
b352c8473a Updated Rector to commit 0348124a5535b99712da4debc136d2e73647b97a
0348124a55 [CodeQuality] Skip Switch_ always returned on ExplicitReturnNullRector (#5800)
2024-04-03 14:17:43 +00:00
Tomas Votruba
6e65fef1e7 Updated Rector to commit 88648d1e6fe18bcc67ea76ebdc76c1d1e6d1fe6f
88648d1e6f [DeadCode] Skip @param true on native bool type on RemoveUselessParamTagRector (#5798)
2024-04-03 13:39:09 +00:00
Tomas Votruba
81fd362a59 Updated Rector to commit 91ed251a8c450a776ec4b739c735b4bd6f9bf8d5
91ed251a8c [DeadCode] Skip property fetch on cond as may be overridden on RemoveAlwaysTrueIfConditionRector (#5796)
2024-04-03 12:13:43 +00:00
Tomas Votruba
a210882e56 Updated Rector to commit e5037921c408b717756a3997e8111ae3729aef08
e5037921c4 Cleanup: use hasByName() over getTagsByName() (#5797)
2024-04-03 12:05:35 +00:00
Tomas Votruba
77aab2e2a3 Updated Rector to commit 3f1ccb3ea131997a435fc2211620e968c6732220
3f1ccb3ea1  Support @immutable phpdoc in RestoreDefaultNullToNullableTypePropertyRector (#5795)
2024-04-03 11:21:35 +00:00
Tomas Votruba
d4fd813b33 Updated Rector to commit f889e416d94cbfcf3734bb2fd4daf678aa11f8a9
f889e416d9 [DeadCode] Remove union with interface on RemoveUselessParamTagRector to make it consistent (#5794)
2024-04-03 07:05:33 +00:00
Tomas Votruba
36ab30b476 Updated Rector to commit 8bce42424e3418ee287fe34b1004b1f66449b923
8bce42424e [NodeTypeResolver] Move UnionType doc vs FullyQualified native type as not equal to TypeComparator (#5793)
2024-04-03 06:36:42 +00:00
Tomas Votruba
3fdaba944f Updated Rector to commit 52aa64ffe2cc0add4cbffede6ce36cbec576ef2f
52aa64ffe2 [DeadCode] Clean up TypeHasher on Union Type (#5792)
2024-04-03 06:21:54 +00:00
Tomas Votruba
dc2feca4d5 Updated Rector to commit ef333de3d58a4649558971b19f4814fd92823abe
ef333de3d5 [DeadCode] Add RemoveUselessReadOnlyTagRector (#5790)
2024-04-03 05:38:43 +00:00
Tomas Votruba
717507e265 Updated Rector to commit 717e3e00ca93c371f8633f6ea17ea1b5e686657a
717e3e00ca [Php81] Remove @readonly doc on transformation to native readonly on ReadOnlyPropertyRector (#5789)
2024-04-03 05:38:25 +00:00
Tomas Votruba
9f2e48fa07 Updated Rector to commit 9b4ad93acd680c5da9a3bab4d5e1f46ad5905b7f
9b4ad93acd Fix removal of useless @param tag when string|null insteadof ?string is used. (#5684)
2024-04-03 05:02:11 +00:00
Tomas Votruba
bc02e10427 Updated Rector to commit b925e54b913863053e57e628ea95b2fd612e128e
b925e54b91 [Performance][Php81] Early property promotion and readonly param check before changeable check on ReadOnlyPropertyRector (#5791)
2024-04-03 04:19:15 +00:00
Tomas Votruba
dc2205094c Updated Rector to commit 724899c28307e4cb1f8a7366ebb76756430da754
724899c283 [TypeDeclaration] Do not use Required::class reference on AutowiredClassMethodOrPropertyAnalyzer (#5788)
2024-04-01 17:58:30 +00:00
Tomas Votruba
664f4e3a6b Updated Rector to commit 0f1987b0faa8dc1c5e086c9b95457d6018b2cd82
0f1987b0fa Adds a link to the PHP Static Analysis Attributes rector rules (#5787)
2024-04-01 16:51:34 +00:00
Tomas Votruba
755e0f4a8c Updated Rector to commit 35c1bf45b0bed6351e0db6e3a44a452f3713b155
35c1bf45b0 [TypeDeclaration] Handle with inner function on AddParamTypeBasedOnPHPUnitDataProviderRector (#5786)
2024-03-31 20:47:44 +00:00
Tomas Votruba
9369a862b6 Updated Rector to commit d86930657fc80c2db725391d1bb8f3ad6a61d96a
d86930657f [TypeDeclaration] Handle in inner function on ReturnTypeFromStrictTernaryRector (#5785)
2024-03-31 19:48:39 +00:00
Tomas Votruba
9b731daab1 Updated Rector to commit 4c40eb60ca984574eea3fa75e8ac59e9c8e07e5e
4c40eb60ca [TypeDeclaration] Handle initialized on getter on ReturnTypeFromStrictTypedPropertyRector (#5784)
2024-03-31 19:07:37 +00:00
Tomas Votruba
0a7d532276 Updated Rector to commit 93e025900b640f8182b267812a08c364d42590ef
93e025900b [automated] Apply Coding Standard (#5782)
2024-03-31 00:30:04 +00:00
Tomas Votruba
f2feb272ed Updated Rector to commit aa706a152c2cb0ece154edab3bc89bad8c2f7208
aa706a152c [Php82] Add VariableInStringInterpolationFixerRector (#5781)
2024-03-29 21:39:12 +00:00
Tomas Votruba
42078c4127 Updated Rector to commit 08d73a1af5ebc77bf37e9854fc1aca76cd5fcbcb
08d73a1af5 [Printer] Apply configurable multiline on Fluent Method Call on print after method call created/re-printed (#5779)
2024-03-28 16:05:42 +00:00
Tomas Votruba
7af3ed15e0 Updated Rector to commit 3122ef482389945d97c26bb3ff5c2b0b3faf867b
3122ef4823 [NodeCollector] Fix non-string value on ArrayCallableMethodMatcher::resolveClassContextType() (#5780)
2024-03-28 09:11:42 +00:00
Tomas Votruba
30adaf3fc0 Updated Rector to commit eb525ca9fe04a8bc074cf49b5cf25991014fff5f
eb525ca9fe [DeadCode] Skip Array Callable dynamic method using __CLASS__ with constructor (no default args) on RemoveUnusedPrivateMethodRector (#5774)
2024-03-28 08:14:50 +00:00
Tomas Votruba
c23b2384d3 Updated Rector to commit 3e6a4923d463e2a2d104ac283dae04343ee2a2d0
3e6a4923d4 [DeadCode] Skip implements interface on RemoveUnusedConstructorParamRector (#5778)
2024-03-27 15:29:07 +00:00
Tomas Votruba
e538a96c9b Updated Rector to commit cd23b1fa90343d4f4b1c8f0d606c0eba8d194597
cd23b1fa90 Clean up scope skip scope check on ExprScopeFromStmtNodeVisitor (#5776)
2024-03-26 20:18:31 +00:00
Tomas Votruba
045db2fd56 Updated Rector to commit f254215a5ac2877d4fb99dbf7f7ab44c070f1333
f254215a5a [Scope] Fix resolve Scope from fluent call (#5743)
2024-03-26 19:25:47 +00:00
Tomas Votruba
014254f0df Updated Rector to commit 83046fcc340c19fc65bc09db25bbc018b01d6f30
83046fcc34 Add `rector` test suite to `phpunit.xml` or `phpunit.xml.dist` (#5717)
2024-03-26 09:28:34 +00:00
Tomas Votruba
4c2b400cdb Updated Rector to commit ff0705b18b7f2e8e7e9062d0d4fd87a4c5c1b20e
ff0705b18b [CodeQuality] Add Goto_ possible return null on SilentVoidResolver under Do_ (#5773)
2024-03-25 15:52:31 +00:00
Tomas Votruba
cc37bbf217 Updated Rector to commit 82d71724f2e2fff036a859e3fe2589fa82adb633
82d71724f2 [TypeDeclaration] Ensure always return with Expr on maybe continued in next stmt on SilentVoidResolver (#5771)
2024-03-25 08:45:48 +00:00
Tomas Votruba
be393d497b Updated Rector to commit fc250dd8da281cb79f5657d2f5d6c6c0053e54d1
fc250dd8da [DeadCode] Fix array callable with constructor args (#5770)
2024-03-24 14:10:21 +00:00
Tomas Votruba
078e4b92d7 Updated Rector to commit 25f3af626f841f7e62606a3a9aa64789a460f74c
25f3af626f [automated] Apply Coding Standard (#5769)
2024-03-24 00:29:59 +00:00
Tomas Votruba
ca1cc37af8 Updated Rector to commit 087f07ae43a3842cf06b257b0ac69e20cac5a14a
087f07ae43 [automated] Re-Generate preload.php (#5768)
2024-03-24 00:29:17 +00:00
Tomas Votruba
5d8e196d67 Updated Rector to commit 11ce9fcc2ca9283af47d2aee343befc111a4e595
11ce9fcc2c More fixture on Do_ maybe returned (#5767)
2024-03-23 20:38:12 +00:00
Tomas Votruba
52addb1dde Updated Rector to commit 879feb8931f1465fa463d539e9ce99ebfae4e948
879feb8931 [CodeQuality] Handle do { } while maybe returned on ExplicitReturnNullRector (#5766)
2024-03-23 20:33:11 +00:00
Tomas Votruba
e14c8a528b Updated Rector to commit aac889be3d845974d3ab924ff7ad22784b9e3cb5
aac889be3d [AutoImport] Remove unused compare removed use on FullyQualifiedNameClassNameImportSkipVoter (#5764)
2024-03-23 16:49:42 +00:00
Tomas Votruba
bb8b99d70c Updated Rector to commit e3e741edd3ca55fc2c24c040f43c8974bda7e953
e3e741edd3 [AutoImport] Allow auto import same namespace with sub use with docblock short name (#5763)
2024-03-23 14:36:19 +00:00
Tomas Votruba
0e57251e46 Updated Rector to commit c45f0e2cef30cb0b3090d51fd14dc6ffaa1fc095
c45f0e2cef [CodeQuality] Add Function_ support on ExplicitReturnNullRector (#5762)
2024-03-23 06:38:28 +00:00
Tomas Votruba
e18e5ef364 Updated Rector to commit 97e2433a8378ccc6666c67d4a01ace3abc97589f
97e2433a83 [CodeQuality] Allow transform return; to return null; when there is other return with Expr on ExplicitReturnNullRector (#5761)
2024-03-23 06:28:38 +00:00
Tomas Votruba
74b8ed7cd4 Updated Rector to commit cae06912ed7d7274d900fdc996448f100be2ed34
cae06912ed [CodeQuality] Skip do { } while always returned on ExplicitReturnNullRector (#5760)
2024-03-23 05:12:50 +00:00
Tomas Votruba
e6bfc79aa2 Updated Rector to commit 8874f25347004e0c19043e8b97b69470193f0941
8874f25347 [CodeQuality] Move Yield_ and YieldFrom check to SilentVoidResolver (#5759)
2024-03-22 20:34:36 +00:00
Tomas Votruba
024ebc62a1 Updated Rector to commit b042152eae866b5578ea15cb38e27ce493937001
b042152eae [CodeQuality] Skip __construct() method on ExplicitReturnNullRector (#5758)
2024-03-22 19:55:35 +00:00
Tomas Votruba
e10d636f62 Updated Rector to commit 61c7e9288885218b76a4a9431bba33a37059dea5
61c7e92888 [CodeQuality] No need to re-update doc when already union null doc on ExplicitReturnNullRector (#5757)
2024-03-22 18:09:58 +00:00
Tomas Votruba
ce9cc3aafc Updated Rector to commit 576198cf701684dd85ed42530bcb8c54b6c41a02
576198cf70 [CodeQuality] Transform type|void docblock to type|null as well on ExplicitReturnNullRector after add return null (#5756)
2024-03-22 17:50:28 +00:00
Tomas Votruba
dd51f7ceed Updated Rector to commit 32bf5c7e7a8da2100f12cbef185c958655d4292d
32bf5c7e7a [CodeQuality] Skip if else return on ExplicitReturnNullRector (#5755)
2024-03-22 16:53:50 +00:00
Tomas Votruba
11b9220a05 Updated Rector to commit b4eb883e9110f50607ce2eed629c237b5e7e7356
b4eb883e91 [DeadCode] Skip isset() from property fetch from docblock on RemoveAlwaysTrueIfConditionRector (#5754)
2024-03-22 00:10:36 +00:00
Tomas Votruba
9811962c70 Updated Rector to commit b4eb883e9110f50607ce2eed629c237b5e7e7356
b4eb883e91 [DeadCode] Skip isset() from property fetch from docblock on RemoveAlwaysTrueIfConditionRector (#5754)
2024-03-21 18:38:10 +00:00
Tomas Votruba
de2b2cf2b4 Updated Rector to commit dc69b1a963dc78ea9fe4ab07b70bc0716e1be341
dc69b1a963 [CodeQuality] Add new rule - ExplicitReturnNullRector (#5753)
2024-03-21 14:39:02 +00:00
Tomas Votruba
1a710b92cc Updated Rector to commit f32dff3ddb3bb8062fced070984017352f2b653a
f32dff3ddb [DeadCode] Skip From docblock on ReduceAlwaysFalseIfOrRector (#5752)
2024-03-21 11:54:51 +00:00
Tomas Votruba
c1338c4c07 Updated Rector to commit aaf006c8f534230b1bbc4c4fb3747cd660305718
aaf006c8f5 [DeadCode] Skip use docblock on BooleanAnd check on RemoveDeadInstanceOfRector (#5751)
2024-03-21 11:37:34 +00:00
Tomas Votruba
50c2e61f1d Updated Rector to commit 0dd1a43904e7d12c76e810b1bbd87d99a0f835c3
0dd1a43904 [DeadCode] Add new rule - ReduceAlwaysFalseIfOrRector (#5750)
2024-03-21 11:36:43 +00:00
Tomas Votruba
7a69e542ca Updated Rector to commit 98a2a6fd6c6d1e2db5c0143e3e66e8421904b428
98a2a6fd6c Add test fixture on boolean && in RemoveAlwaysTrueIfConditionRector (#5749)
2024-03-21 11:23:24 +00:00
Tomas Votruba
c950e4d97b Updated Rector to commit da67bb97a141fd0feb2ab90f5576138489f2f67d
da67bb97a1 Add boolean and support to RemoveDeadInstanceOfRector (#5748)
2024-03-21 11:05:56 +00:00
Tomas Votruba
00697fa4b6 Updated Rector to commit 0c177409ed477e978433597639335fb2a78bc331
0c177409ed Add support for getOneOrNullResult() method in ChildDoctrineRepositoryClassTypeRector (#5747)
2024-03-21 10:03:58 +00:00
Tomas Votruba
817ab2f7cb Updated Rector to commit f4070bb2b2f5c8f7a11063ce35549364c437a9cf
f4070bb2b2 Fix ChildDoctrineRepositoryClassTypeRector for generic type (#5746)
2024-03-21 09:55:11 +00:00
Tomas Votruba
b38b8f3e85 Updated Rector to commit 26890958bc539e9a2234f1457a81d37f5972bf79
26890958bc [Php80] Use identical compare on PromotedPropertyCandidateResolver (#5745)
2024-03-20 14:21:32 +00:00
Tomas Votruba
e94ff85194 Updated Rector to commit 765338ec5a4a725ce9b6788582372f24c09a3f82
765338ec5a [Php80] Skip var property usage on ClassPropertyAssignToConstructorPromotionRector (#5744)
2024-03-20 14:11:05 +00:00
Tomas Votruba
5ac9de7a83 Updated Rector to commit 685ba8a63e904c776033ba85c13f8903952e73e4
685ba8a63e [Renaming][AutoImport] Handle after change annotation to attribute with rename on AnnotationToAttributeRector + RenameClassRector with auto import (#5741)
2024-03-19 14:48:00 +00:00
Tomas Votruba
ceff1cad27 Updated Rector to commit 1bf3947959e10f213a04e4eb626fc2ce428add60
1bf3947959 [CodingStyle] Remove usage of Reflection::expandClassName() from nette/utils 4.0 as cause bug on downgrade (#5740)
2024-03-19 10:36:18 +00:00
Tomas Votruba
ac990f2560 Updated Rector to commit a78fb1b970be42619495215a2612d032a6ecdbee
a78fb1b970 Fix scoper (#5739)
2024-03-19 09:26:21 +00:00
Tomas Votruba
dac0717196 Updated Rector to commit a78fb1b970be42619495215a2612d032a6ecdbee
a78fb1b970 Fix scoper (#5739)
2024-03-19 02:28:26 +00:00
Tomas Votruba
d028a05e61 Updated Rector to commit b052ed9ca971f97105ac93712853ea5b897d4dd3
b052ed9ca9 Handle readonly class with attrs (#5736)
2024-03-19 01:20:27 +00:00
Tomas Votruba
b1eb18f499 Updated Rector to commit b71d0fea8eaf051d6d55aee74c9eece0028e2165
b71d0fea8e Bump rule-doc-generator to prefixed version (#5737)
2024-03-18 22:09:15 +00:00
Tomas Votruba
0268ca2b1c Updated Rector to commit bf856e2ffa55c669e018e773341d7c05794f075e
bf856e2ffa Bump to php-parser ^4.19.1 (#5734)
2024-03-17 08:46:45 +00:00
Tomas Votruba
8d1aee03a3 Updated Rector to commit 560172463933f21b51b8ef306a068dc299f742e5
5601724639 [Dep] Temporary pin to use nikic/php-parser 4.18.0 (#5733)
2024-03-17 07:47:19 +00:00
Tomas Votruba
51090bc214 Updated Rector to commit ac2bd3f825b11233c07235a195f442be4113d99c
ac2bd3f825 [Php81] Skip $this::class on trait on NullToStrictStringFuncCallArgRector (#5732)
2024-03-17 07:10:56 +00:00
Tomas Votruba
b50605a40a Updated Rector to commit 1764c19455ce55ee49ec1d678d422c788e7c4fff
1764c19455 [Configuration] Do not sets, skip, rules on empty array on RectorConfigBuilder (#5731)
2024-03-17 01:39:59 +00:00
Tomas Votruba
2bf9bab235 Updated Rector to commit a94605a3c00447f1f3348b66d0719652cb2aa8ce
a94605a3c0 [automated] Apply Coding Standard (#5730)
2024-03-17 00:29:09 +00:00
Tomas Votruba
29535d04eb Updated Rector to commit 0a07bf39b8c3852a0bd289280ee6e60080561447
0a07bf39b8 [automated] Re-Generate Nodes/Rectors Documentation (#5729)
2024-03-17 00:28:32 +00:00
Tomas Votruba
dd371cdca2 Updated Rector to commit 6477094d5af502e65c75c30af7ce59ef3b8cc2d7
6477094d5a Update ArrayDimFetchToMethodCall to use ObjectType (#5728)
2024-03-16 10:32:26 +00:00
Tomas Votruba
d5d197b9bf Updated Rector to commit d9b64c78e33ef461605ac08578c8159b01839c98
d9b64c78e3 Fixes for ArrayDimFetchToMethodCallRector (#5727)
2024-03-16 09:11:08 +00:00
Tomas Votruba
9ab2b8bc07 Updated Rector to commit d1ed5f03202cb9325f861ac7b8c1976173b45826
d1ed5f0320 [php84] Clean up contains null check type on ExplicitNullableParamTypeRector (#5726)
2024-03-16 08:29:12 +00:00
Tomas Votruba
ae50c0e5a3 Updated Rector to commit cdde425c2224a1357d70d6784936fe47fe3ffee0
cdde425c22 [Transform] Adds ArrayDimFetchToMethodCallRector rule (#5723)
2024-03-15 19:25:11 +00:00
Tomas Votruba
d3357ab3eb Updated Rector to commit a844e40a3f84f120866198401f9b3640575f7c06
a844e40a3f [Composer] Fix double / on illuminate-container-container-php.patch url on extra:patches config (#5725)
2024-03-15 14:15:54 +00:00
Tomas Votruba
c0820093ad Updated Rector to commit ff32c0c08a89f27ea34187d00cf707734a7e39c8
ff32c0c08a [Php84] Add ExplicitNullableParamTypeRector (#5724)
2024-03-15 10:45:55 +00:00
Tomas Votruba
edd8901ea0 Updated Rector to commit 23e3da2d6eee90e4f2a31c31062aabaeba77ba69
23e3da2d6e [CodeQuality] Remove BoolvalToTypeCastRector and FloatvalToTypeCastRector as well from code-quality set (#5722)
2024-03-14 20:16:36 +00:00
Tomas Votruba
d7faacd4a0 Updated Rector to commit ea0f1c1351b68e3a0863d8460e2abea06099df87
ea0f1c1351 [code-quality] Remove intval/strval from sets, as no clear difference and personal preference (#5721)
2024-03-14 15:05:15 +00:00
1220 changed files with 11890 additions and 6517 deletions

View File

@ -101,6 +101,7 @@ Among there projects belong:
* [cakephp/upgrade](https://github.com/cakephp/upgrade) * [cakephp/upgrade](https://github.com/cakephp/upgrade)
* [driftingly/rector-laravel](https://github.com/driftingly/rector-laravel) * [driftingly/rector-laravel](https://github.com/driftingly/rector-laravel)
* [contao/contao-rector](https://github.com/contao/contao-rector) * [contao/contao-rector](https://github.com/contao/contao-rector)
* [php-static-analysis/rector-rule](https://github.com/php-static-analysis/rector-rule)
<br> <br>

View File

@ -2,14 +2,14 @@
// this is part of downgrade build // this is part of downgrade build
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use RectorPrefix202403\Nette\Utils\FileSystem; use RectorPrefix202406\Nette\Utils\FileSystem;
use RectorPrefix202403\Nette\Utils\Json; use RectorPrefix202406\Nette\Utils\Json;
require __DIR__ . '/../vendor/autoload.php'; require __DIR__ . '/../vendor/autoload.php';
$composerJsonFileContents = FileSystem::read(__DIR__ . '/../composer.json'); $composerJsonFileContents = FileSystem::read(__DIR__ . '/../composer.json');
$composerJson = Json::decode($composerJsonFileContents, Json::FORCE_ARRAY); $composerJson = Json::decode($composerJsonFileContents, \true);
$composerJson['replace']['phpstan/phpstan'] = $composerJson['require']['phpstan/phpstan']; $composerJson['replace']['phpstan/phpstan'] = $composerJson['require']['phpstan/phpstan'];
$modifiedComposerJsonFileContents = Json::encode($composerJson, Json::PRETTY); $modifiedComposerJsonFileContents = Json::encode($composerJson, \true);
FileSystem::write(__DIR__ . '/../composer.json', $modifiedComposerJsonFileContents, null); FileSystem::write(__DIR__ . '/../composer.json', $modifiedComposerJsonFileContents, null);
echo 'Done!' . \PHP_EOL; echo 'Done!' . \PHP_EOL;

View File

@ -1,5 +1,5 @@
#!/usr/bin/env php #!/usr/bin/env php
<?php <?php
namespace RectorPrefix202403; namespace RectorPrefix202406;
require_once __DIR__ . '/rector.php'; require_once __DIR__ . '/rector.php';

View File

@ -1,9 +1,9 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use RectorPrefix202403\Nette\Utils\Json; use RectorPrefix202406\Nette\Utils\Json;
use Rector\Bootstrap\RectorConfigsResolver; use Rector\Bootstrap\RectorConfigsResolver;
use Rector\ChangesReporting\Output\JsonOutputFormatter; use Rector\ChangesReporting\Output\JsonOutputFormatter;
use Rector\Configuration\Option; use Rector\Configuration\Option;
@ -11,9 +11,9 @@ use Rector\Console\Style\SymfonyStyleFactory;
use Rector\DependencyInjection\LazyContainerFactory; use Rector\DependencyInjection\LazyContainerFactory;
use Rector\DependencyInjection\RectorContainerFactory; use Rector\DependencyInjection\RectorContainerFactory;
use Rector\Util\Reflection\PrivatesAccessor; use Rector\Util\Reflection\PrivatesAccessor;
use RectorPrefix202403\Symfony\Component\Console\Application; use RectorPrefix202406\Symfony\Component\Console\Application;
use RectorPrefix202403\Symfony\Component\Console\Command\Command; use RectorPrefix202406\Symfony\Component\Console\Command\Command;
use RectorPrefix202403\Symfony\Component\Console\Input\ArgvInput; use RectorPrefix202406\Symfony\Component\Console\Input\ArgvInput;
// @ intentionally: continue anyway // @ intentionally: continue anyway
@\ini_set('memory_limit', '-1'); @\ini_set('memory_limit', '-1');
// Performance boost // Performance boost
@ -93,7 +93,7 @@ final class AutoloadIncluder
require_once $filePath; require_once $filePath;
} }
} }
\class_alias('RectorPrefix202403\\AutoloadIncluder', 'AutoloadIncluder', \false); \class_alias('RectorPrefix202406\\AutoloadIncluder', 'AutoloadIncluder', \false);
if (\file_exists(__DIR__ . '/../preload.php') && \is_dir(__DIR__ . '/../vendor')) { if (\file_exists(__DIR__ . '/../preload.php') && \is_dir(__DIR__ . '/../vendor')) {
require_once __DIR__ . '/../preload.php'; require_once __DIR__ . '/../preload.php';
} }

View File

@ -8,7 +8,7 @@
], ],
"require": { "require": {
"php": "^7.2|^8.0", "php": "^7.2|^8.0",
"phpstan/phpstan": "^1.10.57" "phpstan/phpstan": "^1.11"
}, },
"autoload": { "autoload": {
"files": [ "files": [
@ -22,5 +22,8 @@
"rector/rector-downgrade-php": "*" "rector/rector-downgrade-php": "*"
}, },
"minimum-stability": "dev", "minimum-stability": "dev",
"prefer-stable": true "prefer-stable": true,
"suggest": {
"ext-dom": "To manipulate phpunit.xml via the custom-rule command"
}
} }

View File

@ -1,9 +1,9 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use RectorPrefix202403\OndraM\CiDetector\CiDetector; use RectorPrefix202406\OndraM\CiDetector\CiDetector;
use Rector\Bootstrap\ExtensionConfigResolver; use Rector\Bootstrap\ExtensionConfigResolver;
use Rector\Caching\ValueObject\Storage\MemoryCacheStorage; use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
@ -31,4 +31,6 @@ return static function (RectorConfig $rectorConfig) : void {
foreach ($extensionConfigResolver->provide() as $extensionConfigFile) { foreach ($extensionConfigResolver->provide() as $extensionConfigFile) {
$rectorConfig->import($extensionConfigFile); $rectorConfig->import($extensionConfigFile);
} }
// use original php-parser printer to avoid BC break on fluent call
$rectorConfig->newLineOnFluentCall(\false);
}; };

View File

@ -1,115 +1,15 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector; use Rector\Config\Level\CodeQualityLevel;
use Rector\CodeQuality\Rector\Assign\CombinedAssignRector;
use Rector\CodeQuality\Rector\BooleanAnd\RemoveUselessIsObjectCheckRector;
use Rector\CodeQuality\Rector\BooleanAnd\SimplifyEmptyArrayCheckRector;
use Rector\CodeQuality\Rector\BooleanNot\ReplaceMultipleBooleanNotRector;
use Rector\CodeQuality\Rector\BooleanNot\SimplifyDeMorganBinaryRector;
use Rector\CodeQuality\Rector\Catch_\ThrowWithPreviousExceptionRector;
use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector;
use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\CodeQuality\Rector\Class_\StaticToSelfStaticMethodCallOnFinalClassRector;
use Rector\CodeQuality\Rector\ClassConstFetch\ConvertStaticPrivateConstantToSelfRector;
use Rector\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector;
use Rector\CodeQuality\Rector\ClassMethod\LocallyCalledStaticMethodToNonStaticRector;
use Rector\CodeQuality\Rector\ClassMethod\OptionalParametersAfterRequiredRector;
use Rector\CodeQuality\Rector\Concat\JoinStringConcatRector;
use Rector\CodeQuality\Rector\Empty_\SimplifyEmptyCheckOnEmptyArrayRector;
use Rector\CodeQuality\Rector\Equal\UseIdenticalOverEqualWithSameTypeRector;
use Rector\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector;
use Rector\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector;
use Rector\CodeQuality\Rector\For_\ForRepeatedCountToOwnVariableRector;
use Rector\CodeQuality\Rector\Foreach_\ForeachItemsAssignToEmptyArrayToAssignRector;
use Rector\CodeQuality\Rector\Foreach_\ForeachToInArrayRector;
use Rector\CodeQuality\Rector\Foreach_\SimplifyForeachToCoalescingRector;
use Rector\CodeQuality\Rector\Foreach_\UnusedForeachValueToArrayKeysRector;
use Rector\CodeQuality\Rector\FuncCall\ArrayMergeOfNonArraysToSimpleArrayRector;
use Rector\CodeQuality\Rector\FuncCall\BoolvalToTypeCastRector;
use Rector\CodeQuality\Rector\FuncCall\CallUserFuncWithArrowFunctionToInlineRector;
use Rector\CodeQuality\Rector\FuncCall\ChangeArrayPushToArrayAssignRector;
use Rector\CodeQuality\Rector\FuncCall\CompactToVariablesRector;
use Rector\CodeQuality\Rector\FuncCall\FloatvalToTypeCastRector;
use Rector\CodeQuality\Rector\FuncCall\InlineIsAInstanceOfRector;
use Rector\CodeQuality\Rector\FuncCall\IntvalToTypeCastRector;
use Rector\CodeQuality\Rector\FuncCall\IsAWithStringWithThirdArgumentRector;
use Rector\CodeQuality\Rector\FuncCall\RemoveSoleValueSprintfRector;
use Rector\CodeQuality\Rector\FuncCall\SetTypeToCastRector;
use Rector\CodeQuality\Rector\FuncCall\SimplifyFuncGetArgsCountRector;
use Rector\CodeQuality\Rector\FuncCall\SimplifyInArrayValuesRector;
use Rector\CodeQuality\Rector\FuncCall\SimplifyRegexPatternRector;
use Rector\CodeQuality\Rector\FuncCall\SimplifyStrposLowerRector;
use Rector\CodeQuality\Rector\FuncCall\SingleInArrayToCompareRector;
use Rector\CodeQuality\Rector\FuncCall\StrvalToTypeCastRector;
use Rector\CodeQuality\Rector\FuncCall\UnwrapSprintfOneArgumentRector;
use Rector\CodeQuality\Rector\FunctionLike\SimplifyUselessVariableRector;
use Rector\CodeQuality\Rector\Identical\BooleanNotIdenticalToNotIdenticalRector;
use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector;
use Rector\CodeQuality\Rector\Identical\GetClassToInstanceOfRector;
use Rector\CodeQuality\Rector\Identical\SimplifyArraySearchRector;
use Rector\CodeQuality\Rector\Identical\SimplifyBoolIdenticalTrueRector;
use Rector\CodeQuality\Rector\Identical\SimplifyConditionsRector;
use Rector\CodeQuality\Rector\Identical\StrlenZeroToIdenticalEmptyStringRector;
use Rector\CodeQuality\Rector\If_\CombineIfRector;
use Rector\CodeQuality\Rector\If_\CompleteMissingIfElseBracketRector;
use Rector\CodeQuality\Rector\If_\ConsecutiveNullCompareReturnsToNullCoalesceQueueRector;
use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector;
use Rector\CodeQuality\Rector\If_\ShortenElseIfRector;
use Rector\CodeQuality\Rector\If_\SimplifyIfElseToTernaryRector;
use Rector\CodeQuality\Rector\If_\SimplifyIfNotNullReturnRector;
use Rector\CodeQuality\Rector\If_\SimplifyIfNullableReturnRector;
use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector;
use Rector\CodeQuality\Rector\Include_\AbsolutizeRequireAndIncludePathRector;
use Rector\CodeQuality\Rector\Isset_\IssetOnPropertyObjectToPropertyExistsRector;
use Rector\CodeQuality\Rector\LogicalAnd\AndAssignsToSeparateLinesRector;
use Rector\CodeQuality\Rector\LogicalAnd\LogicalToBooleanRector;
use Rector\CodeQuality\Rector\New_\NewStaticToNewSelfRector;
use Rector\CodeQuality\Rector\NotEqual\CommonNotEqualRector;
use Rector\CodeQuality\Rector\NullsafeMethodCall\CleanupUnneededNullsafeOperatorRector;
use Rector\CodeQuality\Rector\Switch_\SingularSwitchToIfRector;
use Rector\CodeQuality\Rector\Switch_\SwitchTrueToIfRector;
use Rector\CodeQuality\Rector\Ternary\ArrayKeyExistsTernaryThenValueToCoalescingRector;
use Rector\CodeQuality\Rector\Ternary\NumberCompareToMaxFuncCallRector;
use Rector\CodeQuality\Rector\Ternary\SimplifyTautologyTernaryRector;
use Rector\CodeQuality\Rector\Ternary\SwitchNegatedTernaryRector;
use Rector\CodeQuality\Rector\Ternary\TernaryEmptyArrayArrayDimFetchToCoalesceRector;
use Rector\CodeQuality\Rector\Ternary\UnnecessaryTernaryExpressionRector;
use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector;
use Rector\CodingStyle\Rector\FuncCall\CallUserFuncToMethodCallRector;
use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php52\Rector\Property\VarToPublicPropertyRector;
use Rector\Php71\Rector\FuncCall\RemoveExtraParametersRector;
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector;
return static function (RectorConfig $rectorConfig) : void { return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->ruleWithConfiguration(RenameFunctionRector::class, [ foreach (CodeQualityLevel::RULES_WITH_CONFIGURATION as $rectorClass => $configuration) {
'split' => 'explode', $rectorConfig->ruleWithConfiguration($rectorClass, $configuration);
'join' => 'implode', }
'sizeof' => 'count', // the rule order matters, as its used in withCodeQualityLevel() method
# https://www.php.net/manual/en/aliases.php // place the safest rules first, follow by more complex ones
'chop' => 'rtrim', $rectorConfig->rules(CodeQualityLevel::RULES);
'doubleval' => 'floatval',
'gzputs' => 'gzwrites',
'fputs' => 'fwrite',
'ini_alter' => 'ini_set',
'is_double' => 'is_float',
'is_integer' => 'is_int',
'is_long' => 'is_int',
'is_real' => 'is_float',
'is_writeable' => 'is_writable',
'key_exists' => 'array_key_exists',
'pos' => 'current',
'strchr' => 'strstr',
# mb
'mbstrcut' => 'mb_strcut',
'mbstrlen' => 'mb_strlen',
'mbstrpos' => 'mb_strpos',
'mbstrrpos' => 'mb_strrpos',
'mbsubstr' => 'mb_substr',
]);
$rectorConfig->rules([CombinedAssignRector::class, SimplifyEmptyArrayCheckRector::class, ReplaceMultipleBooleanNotRector::class, ForeachToInArrayRector::class, SimplifyForeachToCoalescingRector::class, SimplifyFuncGetArgsCountRector::class, SimplifyInArrayValuesRector::class, SimplifyStrposLowerRector::class, GetClassToInstanceOfRector::class, SimplifyArraySearchRector::class, SimplifyConditionsRector::class, SimplifyIfNotNullReturnRector::class, SimplifyIfReturnBoolRector::class, SimplifyUselessVariableRector::class, UnnecessaryTernaryExpressionRector::class, RemoveExtraParametersRector::class, SimplifyDeMorganBinaryRector::class, SimplifyTautologyTernaryRector::class, SingleInArrayToCompareRector::class, SimplifyIfElseToTernaryRector::class, JoinStringConcatRector::class, ConsecutiveNullCompareReturnsToNullCoalesceQueueRector::class, ExplicitBoolCompareRector::class, CombineIfRector::class, UseIdenticalOverEqualWithSameTypeRector::class, SimplifyBoolIdenticalTrueRector::class, SimplifyRegexPatternRector::class, BooleanNotIdenticalToNotIdenticalRector::class, StrvalToTypeCastRector::class, FloatvalToTypeCastRector::class, CallableThisArrayToAnonymousFunctionRector::class, AndAssignsToSeparateLinesRector::class, CompactToVariablesRector::class, CompleteDynamicPropertiesRector::class, IsAWithStringWithThirdArgumentRector::class, StrlenZeroToIdenticalEmptyStringRector::class, ThrowWithPreviousExceptionRector::class, RemoveSoleValueSprintfRector::class, ShortenElseIfRector::class, ArrayMergeOfNonArraysToSimpleArrayRector::class, IntvalToTypeCastRector::class, BoolvalToTypeCastRector::class, ArrayKeyExistsTernaryThenValueToCoalescingRector::class, AbsolutizeRequireAndIncludePathRector::class, ChangeArrayPushToArrayAssignRector::class, ForRepeatedCountToOwnVariableRector::class, ForeachItemsAssignToEmptyArrayToAssignRector::class, InlineIfToExplicitIfRector::class, UnusedForeachValueToArrayKeysRector::class, CommonNotEqualRector::class, SetTypeToCastRector::class, LogicalToBooleanRector::class, VarToPublicPropertyRector::class, IssetOnPropertyObjectToPropertyExistsRector::class, NewStaticToNewSelfRector::class, UnwrapSprintfOneArgumentRector::class, SwitchNegatedTernaryRector::class, SingularSwitchToIfRector::class, SimplifyIfNullableReturnRector::class, FuncGetArgsToVariadicParamRector::class, CallUserFuncToMethodCallRector::class, CallUserFuncWithArrowFunctionToInlineRector::class, CountArrayToEmptyArrayComparisonRector::class, FlipTypeControlToUseExclusiveTypeRector::class, InlineArrayReturnAssignRector::class, InlineIsAInstanceOfRector::class, TernaryFalseExpressionToIfRector::class, InlineConstructorDefaultToPropertyRector::class, TernaryEmptyArrayArrayDimFetchToCoalesceRector::class, OptionalParametersAfterRequiredRector::class, SimplifyEmptyCheckOnEmptyArrayRector::class, SwitchTrueToIfRector::class, CleanupUnneededNullsafeOperatorRector::class, DisallowedEmptyRuleFixerRector::class, ConvertStaticPrivateConstantToSelfRector::class, LocallyCalledStaticMethodToNonStaticRector::class, NumberCompareToMaxFuncCallRector::class, CompleteMissingIfElseBracketRector::class, RemoveUselessIsObjectCheckRector::class, StaticToSelfStaticMethodCallOnFinalClassRector::class]);
}; };

View File

@ -1,9 +1,8 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\CodingStyle\Rector\ArrowFunction\StaticArrowFunctionRector;
use Rector\CodingStyle\Rector\Assign\SplitDoubleAssignRector; use Rector\CodingStyle\Rector\Assign\SplitDoubleAssignRector;
use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector; use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector;
use Rector\CodingStyle\Rector\ClassConst\RemoveFinalFromConstRector; use Rector\CodingStyle\Rector\ClassConst\RemoveFinalFromConstRector;
@ -11,7 +10,6 @@ use Rector\CodingStyle\Rector\ClassConst\SplitGroupedClassConstantsRector;
use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector; use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector;
use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector; use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector;
use Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector; use Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector;
use Rector\CodingStyle\Rector\Closure\StaticClosureRector;
use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector; use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
use Rector\CodingStyle\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector; use Rector\CodingStyle\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector;
use Rector\CodingStyle\Rector\FuncCall\CallUserFuncArrayToVariadicRector; use Rector\CodingStyle\Rector\FuncCall\CallUserFuncArrayToVariadicRector;
@ -21,8 +19,6 @@ use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
use Rector\CodingStyle\Rector\FuncCall\StrictArraySearchRector; use Rector\CodingStyle\Rector\FuncCall\StrictArraySearchRector;
use Rector\CodingStyle\Rector\FuncCall\VersionCompareFuncCallToConstantRector; use Rector\CodingStyle\Rector\FuncCall\VersionCompareFuncCallToConstantRector;
use Rector\CodingStyle\Rector\If_\NullableCompareToNullRector; use Rector\CodingStyle\Rector\If_\NullableCompareToNullRector;
use Rector\CodingStyle\Rector\Plus\UseIncrementAssignRector;
use Rector\CodingStyle\Rector\PostInc\PostIncDecToPreIncDecRector;
use Rector\CodingStyle\Rector\Property\SplitGroupedPropertiesRector; use Rector\CodingStyle\Rector\Property\SplitGroupedPropertiesRector;
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector; use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
use Rector\CodingStyle\Rector\Stmt\RemoveUselessAliasInUseStatementRector; use Rector\CodingStyle\Rector\Stmt\RemoveUselessAliasInUseStatementRector;
@ -36,5 +32,5 @@ use Rector\Transform\Rector\FuncCall\FuncCallToConstFetchRector;
use Rector\Visibility\Rector\ClassMethod\ExplicitPublicClassMethodRector; use Rector\Visibility\Rector\ClassMethod\ExplicitPublicClassMethodRector;
return static function (RectorConfig $rectorConfig) : void { return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->ruleWithConfiguration(FuncCallToConstFetchRector::class, ['php_sapi_name' => 'PHP_SAPI', 'pi' => 'M_PI']); $rectorConfig->ruleWithConfiguration(FuncCallToConstFetchRector::class, ['php_sapi_name' => 'PHP_SAPI', 'pi' => 'M_PI']);
$rectorConfig->rules([SeparateMultiUseImportsRector::class, PostIncDecToPreIncDecRector::class, NewlineAfterStatementRector::class, RemoveFinalFromConstRector::class, NullableCompareToNullRector::class, ConsistentImplodeRector::class, TernaryConditionVariableAssignmentRector::class, SymplifyQuoteEscapeRector::class, StringClassNameToClassConstantRector::class, CatchExceptionNameMatchingTypeRector::class, UseIncrementAssignRector::class, SplitDoubleAssignRector::class, EncapsedStringsToSprintfRector::class, WrapEncapsedVariableInCurlyBracesRector::class, NewlineBeforeNewAssignSetRector::class, MakeInheritedMethodVisibilitySameAsParentRector::class, CallUserFuncArrayToVariadicRector::class, VersionCompareFuncCallToConstantRector::class, StaticArrowFunctionRector::class, StaticClosureRector::class, CountArrayToEmptyArrayComparisonRector::class, CallUserFuncToMethodCallRector::class, FuncGetArgsToVariadicParamRector::class, StrictArraySearchRector::class, UseClassKeywordForClassNameResolutionRector::class, SplitGroupedPropertiesRector::class, SplitGroupedClassConstantsRector::class, ExplicitPublicClassMethodRector::class, RemoveUselessAliasInUseStatementRector::class]); $rectorConfig->rules([SeparateMultiUseImportsRector::class, NewlineAfterStatementRector::class, RemoveFinalFromConstRector::class, NullableCompareToNullRector::class, ConsistentImplodeRector::class, TernaryConditionVariableAssignmentRector::class, SymplifyQuoteEscapeRector::class, StringClassNameToClassConstantRector::class, CatchExceptionNameMatchingTypeRector::class, SplitDoubleAssignRector::class, EncapsedStringsToSprintfRector::class, WrapEncapsedVariableInCurlyBracesRector::class, NewlineBeforeNewAssignSetRector::class, MakeInheritedMethodVisibilitySameAsParentRector::class, CallUserFuncArrayToVariadicRector::class, VersionCompareFuncCallToConstantRector::class, CountArrayToEmptyArrayComparisonRector::class, CallUserFuncToMethodCallRector::class, FuncGetArgsToVariadicParamRector::class, StrictArraySearchRector::class, UseClassKeywordForClassNameResolutionRector::class, SplitGroupedPropertiesRector::class, SplitGroupedClassConstantsRector::class, ExplicitPublicClassMethodRector::class, RemoveUselessAliasInUseStatementRector::class]);
}; };

View File

@ -0,0 +1,13 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202406;
use Rector\Carbon\Rector\FuncCall\DateFuncCallToCarbonRector;
use Rector\Carbon\Rector\FuncCall\TimeFuncCallToCarbonRector;
use Rector\Carbon\Rector\MethodCall\DateTimeMethodCallToCarbonRector;
use Rector\Carbon\Rector\New_\DateTimeInstanceToCarbonRector;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rules([DateFuncCallToCarbonRector::class, DateTimeInstanceToCarbonRector::class, DateTimeMethodCallToCarbonRector::class, TimeFuncCallToCarbonRector::class]);
};

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\Level\DeadCodeLevel; use Rector\Config\Level\DeadCodeLevel;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector; use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector; use Rector\Renaming\Rector\MethodCall\RenameMethodRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\CodeQuality\Rector\FuncCall\InlineIsAInstanceOfRector; use Rector\CodeQuality\Rector\FuncCall\InlineIsAInstanceOfRector;
use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector; use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\SetList; use Rector\Set\ValueObject\SetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;

View File

@ -0,0 +1,11 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202406;
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->sets([SetList::PHP_84, LevelSetList::UP_TO_PHP_83]);
};

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Naming\Rector\Assign\RenameVariableToMatchMethodCallReturnTypeRector; use Rector\Naming\Rector\Assign\RenameVariableToMatchMethodCallReturnTypeRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php52\Rector\Property\VarToPublicPropertyRector; use Rector\Php52\Rector\Property\VarToPublicPropertyRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php53\Rector\FuncCall\DirNameFileConstantToDirConstantRector; use Rector\Php53\Rector\FuncCall\DirNameFileConstantToDirConstantRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php54\Rector\Array_\LongArrayToShortArrayRector; use Rector\Php54\Rector\Array_\LongArrayToShortArrayRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php55\Rector\Class_\ClassConstantToSelfClassRector; use Rector\Php55\Rector\Class_\ClassConstantToSelfClassRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php56\Rector\FuncCall\PowToExpRector; use Rector\Php56\Rector\FuncCall\PowToExpRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php70\Rector\Assign\ListSplitStringRector; use Rector\Php70\Rector\Assign\ListSplitStringRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php71\Rector\Assign\AssignArrayToStringRector; use Rector\Php71\Rector\Assign\AssignArrayToStringRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php72\Rector\Assign\ListEachRector; use Rector\Php72\Rector\Assign\ListEachRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php52\Rector\Switch_\ContinueToBreakInSwitchRector; use Rector\Php52\Rector\Switch_\ContinueToBreakInSwitchRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector; use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Arguments\Rector\ClassMethod\ArgumentAdderRector; use Rector\Arguments\Rector\ClassMethod\ArgumentAdderRector;
use Rector\Arguments\Rector\FuncCall\FunctionArgumentDefaultValueReplacerRector; use Rector\Arguments\Rector\FuncCall\FunctionArgumentDefaultValueReplacerRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php81\Rector\Array_\FirstClassCallableRector; use Rector\Php81\Rector\Array_\FirstClassCallableRector;

View File

@ -1,12 +1,13 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php82\Rector\Class_\ReadOnlyClassRector; use Rector\Php82\Rector\Class_\ReadOnlyClassRector;
use Rector\Php82\Rector\Encapsed\VariableInStringInterpolationFixerRector;
use Rector\Php82\Rector\FuncCall\Utf8DecodeEncodeToMbConvertEncodingRector; use Rector\Php82\Rector\FuncCall\Utf8DecodeEncodeToMbConvertEncodingRector;
use Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector; use Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector;
return static function (RectorConfig $rectorConfig) : void { return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rules([ReadOnlyClassRector::class, Utf8DecodeEncodeToMbConvertEncodingRector::class, FilesystemIteratorSkipDotsRector::class]); $rectorConfig->rules([ReadOnlyClassRector::class, Utf8DecodeEncodeToMbConvertEncodingRector::class, FilesystemIteratorSkipDotsRector::class, VariableInStringInterpolationFixerRector::class]);
}; };

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php83\Rector\ClassConst\AddTypeToConstRector; use Rector\Php83\Rector\ClassConst\AddTypeToConstRector;

10
config/set/php84.php Normal file
View File

@ -0,0 +1,10 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202406;
use Rector\Config\RectorConfig;
use Rector\Php84\Rector\Param\ExplicitNullableParamTypeRector;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rules([ExplicitNullableParamTypeRector::class]);
};

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector; use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector;

View File

@ -0,0 +1,19 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202406;
use Rector\CodeQuality\Rector\FuncCall\BoolvalToTypeCastRector;
use Rector\CodeQuality\Rector\FuncCall\FloatvalToTypeCastRector;
use Rector\CodeQuality\Rector\FuncCall\IntvalToTypeCastRector;
use Rector\CodeQuality\Rector\FuncCall\StrvalToTypeCastRector;
use Rector\CodingStyle\Rector\Plus\UseIncrementAssignRector;
use Rector\CodingStyle\Rector\PostInc\PostIncDecToPreIncDecRector;
use Rector\Config\RectorConfig;
use Rector\Privatization\Rector\Class_\FinalizeTestCaseClassRector;
use Rector\TypeDeclaration\Rector\BooleanAnd\BinaryOpNullableToInstanceofRector;
use Rector\TypeDeclaration\Rector\StmtsAwareInterface\DeclareStrictTypesRector;
use Rector\TypeDeclaration\Rector\While_\WhileNullableToInstanceofRector;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rules([DeclareStrictTypesRector::class, BinaryOpNullableToInstanceofRector::class, WhileNullableToInstanceofRector::class, IntvalToTypeCastRector::class, StrvalToTypeCastRector::class, BoolvalToTypeCastRector::class, FloatvalToTypeCastRector::class, PostIncDecToPreIncDecRector::class, UseIncrementAssignRector::class, FinalizeTestCaseClassRector::class]);
};

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector; use Rector\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector;

View File

@ -1,7 +1,7 @@
<?php <?php
declare (strict_types=1); declare (strict_types=1);
namespace RectorPrefix202403; namespace RectorPrefix202406;
use Rector\Config\Level\TypeDeclarationLevel; use Rector\Config\Level\TypeDeclarationLevel;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;

View File

@ -1,4 +1,4 @@
# 364 Rules Overview # 380 Rules Overview
<br> <br>
@ -6,11 +6,13 @@
- [Arguments](#arguments) (4) - [Arguments](#arguments) (4)
- [CodeQuality](#codequality) (74) - [Carbon](#carbon) (4)
- [CodeQuality](#codequality) (75)
- [CodingStyle](#codingstyle) (28) - [CodingStyle](#codingstyle) (28)
- [DeadCode](#deadcode) (42) - [DeadCode](#deadcode) (45)
- [EarlyReturn](#earlyreturn) (9) - [EarlyReturn](#earlyreturn) (9)
@ -42,10 +44,12 @@
- [Php81](#php81) (9) - [Php81](#php81) (9)
- [Php82](#php82) (4) - [Php82](#php82) (5)
- [Php83](#php83) (3) - [Php83](#php83) (3)
- [Php84](#php84) (1)
- [Privatization](#privatization) (5) - [Privatization](#privatization) (5)
- [Removing](#removing) (5) - [Removing](#removing) (5)
@ -54,9 +58,9 @@
- [Strict](#strict) (5) - [Strict](#strict) (5)
- [Transform](#transform) (24) - [Transform](#transform) (25)
- [TypeDeclaration](#typedeclaration) (45) - [TypeDeclaration](#typedeclaration) (50)
- [Visibility](#visibility) (3) - [Visibility](#visibility) (3)
@ -140,6 +144,78 @@ Replaces defined map of arguments in defined methods and their calls.
<br> <br>
## Carbon
### DateFuncCallToCarbonRector
Convert `date()` function call to `Carbon::now()->format(*)`
- class: [`Rector\Carbon\Rector\FuncCall\DateFuncCallToCarbonRector`](../rules/Carbon/Rector/FuncCall/DateFuncCallToCarbonRector.php)
```diff
class SomeClass
{
public function run()
{
- $date = date('Y-m-d');
+ $date = \Carbon\Carbon::now()->format('Y-m-d');
}
}
```
<br>
### DateTimeInstanceToCarbonRector
Convert new `DateTime()` to Carbon::*()
- class: [`Rector\Carbon\Rector\New_\DateTimeInstanceToCarbonRector`](../rules/Carbon/Rector/New_/DateTimeInstanceToCarbonRector.php)
```diff
-$date = new \DateTime('today');
+$date = \Carbon\Carbon::today();
```
<br>
### DateTimeMethodCallToCarbonRector
Convert new `DateTime()` with a method call to Carbon::*()
- class: [`Rector\Carbon\Rector\MethodCall\DateTimeMethodCallToCarbonRector`](../rules/Carbon/Rector/MethodCall/DateTimeMethodCallToCarbonRector.php)
```diff
class SomeClass
{
public function run()
{
- $date = (new \DateTime('today +20 day'))->format('Y-m-d');
+ $date = \Carbon\Carbon::today()->addDays(20)->format('Y-m-d')
}
}
```
<br>
### TimeFuncCallToCarbonRector
Convert `time()` function call to `Carbon::now()->timestamp`
- class: [`Rector\Carbon\Rector\FuncCall\TimeFuncCallToCarbonRector`](../rules/Carbon/Rector/FuncCall/TimeFuncCallToCarbonRector.php)
```diff
class SomeClass
{
public function run()
{
- $time = time();
+ $time = \Carbon\Carbon::now()->timestamp;
}
}
```
<br>
## CodeQuality ## CodeQuality
### AbsolutizeRequireAndIncludePathRector ### AbsolutizeRequireAndIncludePathRector
@ -547,6 +623,32 @@ Make if conditions more explicit
<br> <br>
### ExplicitReturnNullRector
Add explicit return null to method/function that returns a value, but missed main return
- class: [`Rector\CodeQuality\Rector\ClassMethod\ExplicitReturnNullRector`](../rules/CodeQuality/Rector/ClassMethod/ExplicitReturnNullRector.php)
```diff
class SomeClass
{
/**
- * @return string|void
+ * @return string|null
*/
public function run(int $number)
{
if ($number > 50) {
return 'yes';
}
+
+ return null;
}
}
```
<br>
### FlipTypeControlToUseExclusiveTypeRector ### FlipTypeControlToUseExclusiveTypeRector
Flip type control from null compare to use exclusive instanceof object Flip type control from null compare to use exclusive instanceof object
@ -2155,6 +2257,29 @@ Removes recasting of the same type
<br> <br>
### ReduceAlwaysFalseIfOrRector
Reduce always false in a if ( || ) condition
- class: [`Rector\DeadCode\Rector\If_\ReduceAlwaysFalseIfOrRector`](../rules/DeadCode/Rector/If_/ReduceAlwaysFalseIfOrRector.php)
```diff
class SomeClass
{
public function run(int $number)
{
- if (! is_int($number) || $number > 50) {
+ if ($number > 50) {
return 'yes';
}
return 'no';
}
}
```
<br>
### RemoveAlwaysTrueIfConditionRector ### RemoveAlwaysTrueIfConditionRector
Remove if condition that is always true Remove if condition that is always true
@ -2796,6 +2921,25 @@ Remove unused promoted property
<br> <br>
### RemoveUnusedPublicMethodParameterRector
Remove unused parameter in public method on final class without extends and interface
- class: [`Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPublicMethodParameterRector`](../rules/DeadCode/Rector/ClassMethod/RemoveUnusedPublicMethodParameterRector.php)
```diff
final class SomeClass
{
- public function run($a, $b)
+ public function run($a)
{
echo $a;
}
}
```
<br>
### RemoveUnusedVariableAssignRector ### RemoveUnusedVariableAssignRector
Remove unused assigns to variables Remove unused assigns to variables
@ -2835,6 +2979,29 @@ Remove `@param` docblock with same type as parameter type
<br> <br>
### RemoveUselessReadOnlyTagRector
Remove useless `@readonly` annotation on native readonly type
- class: [`Rector\DeadCode\Rector\Property\RemoveUselessReadOnlyTagRector`](../rules/DeadCode/Rector/Property/RemoveUselessReadOnlyTagRector.php)
```diff
final class SomeClass
{
- /**
- * @readonly
- */
private readonly string $name;
public function __construct(string $name)
{
$this->name = $name;
}
}
```
<br>
### RemoveUselessReturnExprInConstructRector ### RemoveUselessReturnExprInConstructRector
Remove useless return Expr in `__construct()` Remove useless return Expr in `__construct()`
@ -5272,6 +5439,20 @@ Change deprecated utf8_decode and utf8_encode to mb_convert_encoding
<br> <br>
### VariableInStringInterpolationFixerRector
Replace deprecated "${var}" to "{$var}"
- class: [`Rector\Php82\Rector\Encapsed\VariableInStringInterpolationFixerRector`](../rules/Php82/Rector/Encapsed/VariableInStringInterpolationFixerRector.php)
```diff
$c = "football";
-echo "I like playing ${c}";
+echo "I like playing {$c}";
```
<br>
## Php83 ## Php83
### AddOverrideAttributeToOverriddenMethodsRector ### AddOverrideAttributeToOverriddenMethodsRector
@ -5301,7 +5482,7 @@ Add override attribute to overridden methods
### AddTypeToConstRector ### AddTypeToConstRector
Add const to type Add type to constants
- class: [`Rector\Php83\Rector\ClassConst\AddTypeToConstRector`](../rules/Php83/Rector/ClassConst/AddTypeToConstRector.php) - class: [`Rector\Php83\Rector\ClassConst\AddTypeToConstRector`](../rules/Php83/Rector/ClassConst/AddTypeToConstRector.php)
@ -5328,6 +5509,21 @@ Combine separated host and port on `ldap_connect()` args
<br> <br>
## Php84
### ExplicitNullableParamTypeRector
Make implicit nullable param to explicit
- class: [`Rector\Php84\Rector\Param\ExplicitNullableParamTypeRector`](../rules/Php84/Rector/Param/ExplicitNullableParamTypeRector.php)
```diff
-function foo(string $param = null) {}
+function foo(?string $param = null) {}
```
<br>
## Privatization ## Privatization
### FinalizeClassesWithoutChildrenRector ### FinalizeClassesWithoutChildrenRector
@ -5356,10 +5552,10 @@ PHPUnit test case will be finalized
- class: [`Rector\Privatization\Rector\Class_\FinalizeTestCaseClassRector`](../rules/Privatization/Rector/Class_/FinalizeTestCaseClassRector.php) - class: [`Rector\Privatization\Rector\Class_\FinalizeTestCaseClassRector`](../rules/Privatization/Rector/Class_/FinalizeTestCaseClassRector.php)
```diff ```diff
-use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
+final use PHPUnit\Framework\TestCase;
class SomeClass extends TestCase -class SomeClass extends TestCase
+final class SomeClass extends TestCase
{ {
} }
``` ```
@ -5852,6 +6048,21 @@ Add interface by used trait
<br> <br>
### ArrayDimFetchToMethodCallRector
Change array dim fetch to method call
:wrench: **configure it!**
- class: [`Rector\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector`](../rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php)
```diff
-$app['someService'];
+$app->make('someService');
```
<br>
### AttributeKeyToClassConstFetchRector ### AttributeKeyToClassConstFetchRector
Replace key value on specific attribute to class constant Replace key value on specific attribute to class constant
@ -6584,6 +6795,37 @@ Add void to PHPUnit test methods
<br> <br>
### AddTypeFromResourceDocblockRector
Add param and return types on resource docblock
:wrench: **configure it!**
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\AddTypeFromResourceDocblockRector`](../rules/TypeDeclaration/Rector/ClassMethod/AddTypeFromResourceDocblockRector.php)
```diff
class SomeClass
{
- /**
- * @param resource|null $resource
- */
- public function setResource($resource)
+ public function setResource(?App\ValueObject\Resource $resource)
{
}
- /**
- * @return resource|null
- */
- public function getResource()
+ public function getResource(): ?App\ValueObject\Resource
{
}
}
```
<br>
### AddVoidReturnTypeWhereNoReturnRector ### AddVoidReturnTypeWhereNoReturnRector
Add return type void to function like without any return Add return type void to function like without any return
@ -6649,7 +6891,7 @@ Change return type based on strict returns type operations
### ChildDoctrineRepositoryClassTypeRector ### ChildDoctrineRepositoryClassTypeRector
Add return type to classes that extend `Doctrine\ORM\EntityRepository` Add return type to classes that extend `Doctrine\ORM\EntityRepository` based on return Doctrine method names
- class: [`Rector\TypeDeclaration\Rector\Class_\ChildDoctrineRepositoryClassTypeRector`](../rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php) - class: [`Rector\TypeDeclaration\Rector\Class_\ChildDoctrineRepositoryClassTypeRector`](../rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php)
@ -6712,6 +6954,24 @@ Change `empty()` on nullable object to instanceof check
<br> <br>
### IncreaseDeclareStrictTypesRector
Add declare strict types to a limited amount of classes at a time, to try out in the wild and increase level gradually
:wrench: **configure it!**
- class: [`Rector\TypeDeclaration\Rector\StmtsAwareInterface\IncreaseDeclareStrictTypesRector`](../rules/TypeDeclaration/Rector/StmtsAwareInterface/IncreaseDeclareStrictTypesRector.php)
```diff
+declare(strict_types=1);
+
function someFunction()
{
}
```
<br>
### MergeDateTimePropertyTypeDeclarationRector ### MergeDateTimePropertyTypeDeclarationRector
Set DateTime to DateTimeInterface for DateTime property with DateTimeInterface docblock Set DateTime to DateTimeInterface for DateTime property with DateTimeInterface docblock
@ -6852,6 +7112,30 @@ Add "never" return-type for methods that never return anything
<br> <br>
### ReturnTypeFromReturnCastRector
Add return type to function like with return cast
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnCastRector`](../rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnCastRector.php)
```diff
final class SomeClass
{
- public function action($param)
+ public function action($param): array
{
try {
return (array) $param;
} catch (Exception $exception) {
// some logging
throw $exception;
}
}
}
```
<br>
### ReturnTypeFromReturnDirectArrayRector ### ReturnTypeFromReturnDirectArrayRector
Add return type from return direct array Add return type from return direct array
@ -7103,6 +7387,27 @@ Add return method return type based on strict typed property
<br> <br>
### ReturnTypeFromSymfonySerializerRector
Add return type from symfony serializer
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromSymfonySerializerRector`](../rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromSymfonySerializerRector.php)
```diff
final class SomeClass
{
private \Symfony\Component\Serializer\Serializer $serializer;
- public function resolveEntity($data)
+ public function resolveEntity($data): SomeType
{
return $this->serializer->deserialize($data, SomeType::class, 'json');
}
}
```
<br>
### ReturnUnionTypeRector ### ReturnUnionTypeRector
Add union return type Add union return type
@ -7191,6 +7496,23 @@ Add typed property from assigned types
<br> <br>
### TypedPropertyFromJMSSerializerAttributeTypeRector
Add typed property from JMS Serializer Type attribute
- class: [`Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromJMSSerializerAttributeTypeRector`](../rules/TypeDeclaration/Rector/Class_/TypedPropertyFromJMSSerializerAttributeTypeRector.php)
```diff
final class SomeClass
{
#[\JMS\Serializer\Annotation\Type('string')]
- private $name;
+ private ?string $name = null;
}
```
<br>
### TypedPropertyFromStrictConstructorRector ### TypedPropertyFromStrictConstructorRector
Add typed properties based only on strict constructor types Add typed properties based only on strict constructor types

View File

@ -291,6 +291,9 @@ require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/InvalidTagV
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueNode.php'; require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueParameterNode.php'; require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueParameterNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MixinTagValueNode.php'; require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MixinTagValueNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamClosureThisTagValueNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamImmediatelyInvokedCallableTagValueNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamLaterInvokedCallableTagValueNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamOutTagValueNode.php'; require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamOutTagValueNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamTagValueNode.php'; require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamTagValueNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocChildNode.php'; require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocChildNode.php';

View File

@ -4,7 +4,6 @@ declare (strict_types=1);
namespace Rector\Arguments; namespace Rector\Arguments;
use PhpParser\BuilderHelpers; use PhpParser\BuilderHelpers;
use PhpParser\Node;
use PhpParser\Node\Arg; use PhpParser\Node\Arg;
use PhpParser\Node\Expr; use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ClassConstFetch; use PhpParser\Node\Expr\ClassConstFetch;
@ -35,9 +34,12 @@ final class ArgumentDefaultValueReplacer
$this->valueResolver = $valueResolver; $this->valueResolver = $valueResolver;
} }
/** /**
* @template TCall as (MethodCall|StaticCall|ClassMethod|FuncCall|New_)
*
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\New_ $node * @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\New_ $node
* @return TCall|null
*/ */
public function processReplaces($node, ReplaceArgumentDefaultValueInterface $replaceArgumentDefaultValue) : ?Node public function processReplaces($node, ReplaceArgumentDefaultValueInterface $replaceArgumentDefaultValue)
{ {
if ($node instanceof ClassMethod) { if ($node instanceof ClassMethod) {
if (!isset($node->params[$replaceArgumentDefaultValue->getPosition()])) { if (!isset($node->params[$replaceArgumentDefaultValue->getPosition()])) {
@ -78,7 +80,10 @@ final class ArgumentDefaultValueReplacer
return $classMethod; return $classMethod;
} }
/** /**
* @template TCall as (MethodCall|StaticCall|FuncCall|New_)
*
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\New_ $expr * @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\New_ $expr
* @return TCall|null
*/ */
private function processArgs($expr, ReplaceArgumentDefaultValueInterface $replaceArgumentDefaultValue) : ?Expr private function processArgs($expr, ReplaceArgumentDefaultValueInterface $replaceArgumentDefaultValue) : ?Expr
{ {

View File

@ -29,7 +29,7 @@ use Rector\Rector\AbstractRector;
use Rector\StaticTypeMapper\StaticTypeMapper; use Rector\StaticTypeMapper\StaticTypeMapper;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix202403\Webmozart\Assert\Assert; use RectorPrefix202406\Webmozart\Assert\Assert;
/** /**
* @see \Rector\Tests\Arguments\Rector\ClassMethod\ArgumentAdderRector\ArgumentAdderRectorTest * @see \Rector\Tests\Arguments\Rector\ClassMethod\ArgumentAdderRector\ArgumentAdderRectorTest
*/ */

View File

@ -15,7 +15,7 @@ use Rector\Rector\AbstractRector;
use Rector\ValueObject\MethodName; use Rector\ValueObject\MethodName;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix202403\Webmozart\Assert\Assert; use RectorPrefix202406\Webmozart\Assert\Assert;
/** /**
* @api used in rector-symfony * @api used in rector-symfony
* @see \Rector\Tests\Arguments\Rector\ClassMethod\ReplaceArgumentDefaultValueRector\ReplaceArgumentDefaultValueRectorTest * @see \Rector\Tests\Arguments\Rector\ClassMethod\ReplaceArgumentDefaultValueRector\ReplaceArgumentDefaultValueRectorTest

View File

@ -11,7 +11,7 @@ use Rector\Contract\Rector\ConfigurableRectorInterface;
use Rector\Rector\AbstractRector; use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix202403\Webmozart\Assert\Assert; use RectorPrefix202406\Webmozart\Assert\Assert;
/** /**
* @changelog https://php.watch/versions/8.1/version_compare-operator-restrictions * @changelog https://php.watch/versions/8.1/version_compare-operator-restrictions
* @changelog https://github.com/rectorphp/rector/issues/6271 * @changelog https://github.com/rectorphp/rector/issues/6271

View File

@ -11,7 +11,7 @@ use Rector\Contract\Rector\ConfigurableRectorInterface;
use Rector\Rector\AbstractRector; use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix202403\Webmozart\Assert\Assert; use RectorPrefix202406\Webmozart\Assert\Assert;
/** /**
* @see \Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\RemoveMethodCallParamRectorTest * @see \Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\RemoveMethodCallParamRectorTest
*/ */

View File

@ -0,0 +1,58 @@
<?php
declare (strict_types=1);
namespace Rector\Carbon\NodeFactory;
use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
final class CarbonCallFactory
{
/**
* @var string
* @see https://regex101.com/r/9vGt8r/1
*/
private const DAY_COUNT_REGEX = '#\\+(\\s+)?(?<count>\\d+)(\\s+)?(day|days)#';
/**
* @var string
* @see https://regex101.com/r/6VUUQF/1
*/
private const MONTH_COUNT_REGEX = '#\\+(\\s+)?(?<count>\\d+)(\\s+)?(month|months)#';
/**
* @var array<self::*_REGEX, string>
*/
private const REGEX_TO_METHOD_NAME_MAP = [self::DAY_COUNT_REGEX => 'addDays', self::MONTH_COUNT_REGEX => 'addMonths'];
/**
* @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall
*/
public function createFromDateTimeString(FullyQualified $carbonFullyQualified, String_ $string)
{
$dateTimeValue = $string->value;
if ($dateTimeValue === 'now') {
return new StaticCall($carbonFullyQualified, new Identifier('now'));
}
if ($dateTimeValue === 'today') {
return new StaticCall($carbonFullyQualified, new Identifier('today'));
}
$hasToday = Strings::match($dateTimeValue, '#today#');
if ($hasToday !== null) {
$carbonCall = new StaticCall($carbonFullyQualified, new Identifier('today'));
} else {
$carbonCall = new StaticCall($carbonFullyQualified, new Identifier('now'));
}
foreach (self::REGEX_TO_METHOD_NAME_MAP as $regex => $methodName) {
$match = Strings::match($dateTimeValue, $regex);
if ($match === null) {
continue;
}
$countLNumber = new LNumber((int) $match['count']);
$carbonCall = new MethodCall($carbonCall, new Identifier($methodName), [new Arg($countLNumber)]);
}
return $carbonCall;
}
}

View File

@ -0,0 +1,72 @@
<?php
declare (strict_types=1);
namespace Rector\Carbon\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\String_;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\Carbon\Rector\FuncCall\DateFuncCallToCarbonRector\DateFuncCallToCarbonRectorTest
*/
final class DateFuncCallToCarbonRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Convert date() function call to Carbon::now()->format(*)', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$date = date('Y-m-d');
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$date = \Carbon\Carbon::now()->format('Y-m-d');
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [FuncCall::class];
}
/**
* @param FuncCall $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isName($node->name, 'date')) {
return null;
}
if ($node->isFirstClassCallable()) {
return null;
}
if (\count($node->getArgs()) !== 1) {
return null;
}
$firstArg = $node->getArgs()[0];
if (!$firstArg->value instanceof String_) {
return null;
}
// create now and format()
$nowStaticCall = new StaticCall(new FullyQualified('Carbon\\Carbon'), 'now');
return new MethodCall($nowStaticCall, 'format', [new Arg($firstArg->value)]);
}
}

View File

@ -0,0 +1,69 @@
<?php
declare (strict_types=1);
namespace Rector\Carbon\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Expr\ArrowFunction;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name\FullyQualified;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\Carbon\Rector\FuncCall\DateFuncCallToCarbonRector\DateFuncCallToCarbonRectorTest
*/
final class TimeFuncCallToCarbonRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Convert time() function call to Carbon::now()->timestamp', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$time = time();
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$time = \Carbon\Carbon::now()->timestamp;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [FuncCall::class];
}
/**
* @param FuncCall $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isName($node->name, 'time')) {
return null;
}
$firstClassCallable = $node->isFirstClassCallable();
if (!$firstClassCallable && \count($node->getArgs()) !== 0) {
return null;
}
// create now and format()
$nowStaticCall = new StaticCall(new FullyQualified('Carbon\\Carbon'), 'now');
$propertyFetch = new PropertyFetch($nowStaticCall, 'timestamp');
if ($firstClassCallable) {
return new ArrowFunction(['static' => \true, 'expr' => $propertyFetch]);
}
return $propertyFetch;
}
}

View File

@ -0,0 +1,94 @@
<?php
declare (strict_types=1);
namespace Rector\Carbon\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\String_;
use Rector\Carbon\NodeFactory\CarbonCallFactory;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\Carbon\Rector\MethodCall\DateTimeMethodCallToCarbonRector\DateTimeMethodCallToCarbonRectorTest
*/
final class DateTimeMethodCallToCarbonRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\Carbon\NodeFactory\CarbonCallFactory
*/
private $carbonCallFactory;
public function __construct(CarbonCallFactory $carbonCallFactory)
{
$this->carbonCallFactory = $carbonCallFactory;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Convert new DateTime() with a method call to Carbon::*()', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$date = (new \DateTime('today +20 day'))->format('Y-m-d');
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$date = \Carbon\Carbon::today()->addDays(20)->format('Y-m-d')
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node) : ?Node
{
if (!$node->var instanceof New_) {
return null;
}
$new = $node->var;
if (!$new->class instanceof Name) {
return null;
}
if (!$this->isName($new->class, 'DateTime') && !$this->isName($new->class, 'DateTimeImmutable')) {
return null;
}
if ($new->isFirstClassCallable()) {
return null;
}
if (\count($new->getArgs()) !== 1) {
// @todo handle in separate static call
return null;
}
$firstArg = $new->getArgs()[0];
if (!$firstArg->value instanceof String_) {
return null;
}
if ($this->isName($new->class, 'DateTime')) {
$carbonFullyQualified = new FullyQualified('Carbon\\Carbon');
} else {
$carbonFullyQualified = new FullyQualified('Carbon\\CarbonImmutable');
}
$carbonCall = $this->carbonCallFactory->createFromDateTimeString($carbonFullyQualified, $firstArg->value);
$node->var = $carbonCall;
return $node;
}
}

View File

@ -0,0 +1,84 @@
<?php
declare (strict_types=1);
namespace Rector\Carbon\Rector\New_;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\String_;
use Rector\Carbon\NodeFactory\CarbonCallFactory;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://github.com/briannesbitt/Carbon/issues/231
*
* @see \Rector\Tests\Carbon\Rector\New_\DateTimeInstanceToCarbonRector\DateTimeInstanceToCarbonRectorTest
*/
final class DateTimeInstanceToCarbonRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\Carbon\NodeFactory\CarbonCallFactory
*/
private $carbonCallFactory;
public function __construct(CarbonCallFactory $carbonCallFactory)
{
$this->carbonCallFactory = $carbonCallFactory;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Convert new DateTime() to Carbon::*()', [new CodeSample(<<<'CODE_SAMPLE'
$date = new \DateTime('today');
CODE_SAMPLE
, <<<'CODE_SAMPLE'
$date = \Carbon\Carbon::today();
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [New_::class];
}
/**
* @param New_ $node
*/
public function refactor(Node $node) : ?Node
{
if ($node->isFirstClassCallable()) {
return null;
}
if ($this->isName($node->class, 'DateTime')) {
return $this->refactorWithClass($node, 'Carbon\\Carbon');
}
if ($this->isName($node->class, 'DateTimeImmutable')) {
return $this->refactorWithClass($node, 'Carbon\\CarbonImmutable');
}
return null;
}
/**
* @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|null
*/
private function refactorWithClass(New_ $new, string $className)
{
// no arg? ::now()
$carbonFullyQualified = new FullyQualified($className);
if ($new->args === []) {
return new StaticCall($carbonFullyQualified, new Identifier('now'));
}
if (\count($new->getArgs()) === 1) {
$firstArg = $new->getArgs()[0];
if ($firstArg->value instanceof String_) {
return $this->carbonCallFactory->createFromDateTimeString($carbonFullyQualified, $firstArg->value);
}
}
return null;
}
}

View File

@ -5,6 +5,9 @@ namespace Rector\CodeQuality\Rector\Array_;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\Property;
use PhpParser\NodeTraverser;
use PHPStan\Analyser\Scope; use PHPStan\Analyser\Scope;
use PHPStan\Reflection\Php\PhpMethodReflection; use PHPStan\Reflection\Php\PhpMethodReflection;
use Rector\NodeCollector\NodeAnalyzer\ArrayCallableMethodMatcher; use Rector\NodeCollector\NodeAnalyzer\ArrayCallableMethodMatcher;
@ -20,6 +23,9 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
* @changelog https://3v4l.org/KM1Ji * @changelog https://3v4l.org/KM1Ji
* *
* @see \Rector\Tests\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector\CallableThisArrayToAnonymousFunctionRectorTest * @see \Rector\Tests\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector\CallableThisArrayToAnonymousFunctionRectorTest
*
* @deprecated This rule is surpassed by more advanced one
* Use @see FirstClassCallableRector instead
*/ */
final class CallableThisArrayToAnonymousFunctionRector extends AbstractScopeAwareRector final class CallableThisArrayToAnonymousFunctionRector extends AbstractScopeAwareRector
{ {
@ -89,13 +95,17 @@ CODE_SAMPLE
*/ */
public function getNodeTypes() : array public function getNodeTypes() : array
{ {
return [Array_::class]; return [Property::class, ClassConst::class, Array_::class];
} }
/** /**
* @param Array_ $node * @param Property|ClassConst|Array_ $node
* @return null|int|\PhpParser\Node
*/ */
public function refactorWithScope(Node $node, Scope $scope) : ?Node public function refactorWithScope(Node $node, Scope $scope)
{ {
if ($node instanceof Property || $node instanceof ClassConst) {
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
}
if ($this->shouldSkipTwigExtension($scope)) { if ($this->shouldSkipTwigExtension($scope)) {
return null; return null;
} }

View File

@ -0,0 +1,174 @@
<?php
declare (strict_types=1);
namespace Rector\CodeQuality\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use PhpParser\NodeTraverser;
use PHPStan\Type\NullType;
use PHPStan\Type\UnionType;
use PHPStan\Type\VoidType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Rector\Rector\AbstractRector;
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
use Rector\TypeDeclaration\TypeInferer\SilentVoidResolver;
use Rector\ValueObject\MethodName;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\CodeQuality\Rector\ClassMethod\ExplicitReturnNullRector\ExplicitReturnNullRectorTest
*/
final class ExplicitReturnNullRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\TypeDeclaration\TypeInferer\SilentVoidResolver
*/
private $silentVoidResolver;
/**
* @readonly
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
*/
private $phpDocInfoFactory;
/**
* @readonly
* @var \Rector\NodeTypeResolver\PHPStan\Type\TypeFactory
*/
private $typeFactory;
/**
* @readonly
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger
*/
private $phpDocTypeChanger;
/**
* @readonly
* @var \Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer
*/
private $returnTypeInferer;
public function __construct(SilentVoidResolver $silentVoidResolver, PhpDocInfoFactory $phpDocInfoFactory, TypeFactory $typeFactory, PhpDocTypeChanger $phpDocTypeChanger, ReturnTypeInferer $returnTypeInferer)
{
$this->silentVoidResolver = $silentVoidResolver;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->typeFactory = $typeFactory;
$this->phpDocTypeChanger = $phpDocTypeChanger;
$this->returnTypeInferer = $returnTypeInferer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Add explicit return null to method/function that returns a value, but missed main return', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
/**
* @return string|void
*/
public function run(int $number)
{
if ($number > 50) {
return 'yes';
}
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
/**
* @return string|null
*/
public function run(int $number)
{
if ($number > 50) {
return 'yes';
}
return null;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class, Function_::class];
}
/**
* @param ClassMethod|Function_ $node
*/
public function refactor(Node $node) : ?Node
{
// known return type, nothing to improve
if ($node->returnType instanceof Node) {
return null;
}
if ($node instanceof ClassMethod && $this->isName($node, MethodName::CONSTRUCT)) {
return null;
}
$returnType = $this->returnTypeInferer->inferFunctionLike($node);
if (!$returnType instanceof UnionType) {
return null;
}
$hasChanged = \false;
$this->traverseNodesWithCallable((array) $node->stmts, static function (Node $node) use(&$hasChanged) {
if ($node instanceof Class_ || $node instanceof Function_ || $node instanceof Closure) {
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
}
if ($node instanceof Return_ && !$node->expr instanceof Expr) {
$hasChanged = \true;
$node->expr = new ConstFetch(new Name('null'));
return $node;
}
return null;
});
if (!$this->silentVoidResolver->hasSilentVoid($node)) {
if ($hasChanged) {
$this->transformDocUnionVoidToUnionNull($node);
return $node;
}
return null;
}
$node->stmts[] = new Return_(new ConstFetch(new Name('null')));
$this->transformDocUnionVoidToUnionNull($node);
return $node;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $node
*/
private function transformDocUnionVoidToUnionNull($node) : void
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$returnType = $phpDocInfo->getReturnType();
if (!$returnType instanceof UnionType) {
return;
}
$newTypes = [];
$hasChanged = \false;
foreach ($returnType->getTypes() as $type) {
if ($type instanceof VoidType) {
$type = new NullType();
$hasChanged = \true;
}
$newTypes[] = $type;
}
if (!$hasChanged) {
return;
}
$type = $this->typeFactory->createMixedPassedOrUnionTypeAndKeepConstant($newTypes);
if (!$type instanceof UnionType) {
return;
}
$this->phpDocTypeChanger->changeReturnType($node, $phpDocInfo, $type);
}
}

View File

@ -4,12 +4,16 @@ declare (strict_types=1);
namespace Rector\CodeQuality\Rector\ClassMethod; namespace Rector\CodeQuality\Rector\ClassMethod;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_; use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PHPStan\Analyser\Scope; use PHPStan\Analyser\Scope;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\MethodReflection; use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\Native\NativeFunctionReflection;
use Rector\CodingStyle\Reflection\VendorLocationDetector; use Rector\CodingStyle\Reflection\VendorLocationDetector;
use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper; use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper;
use Rector\Php80\NodeResolver\ArgumentSorter; use Rector\Php80\NodeResolver\ArgumentSorter;
@ -81,41 +85,49 @@ CODE_SAMPLE
*/ */
public function getNodeTypes() : array public function getNodeTypes() : array
{ {
return [ClassMethod::class, New_::class, MethodCall::class, StaticCall::class]; return [ClassMethod::class, Function_::class, New_::class, MethodCall::class, StaticCall::class, FuncCall::class];
} }
/** /**
* @param ClassMethod|New_|MethodCall|StaticCall $node * @param ClassMethod|Function_|New_|MethodCall|StaticCall|FuncCall $node
* @return \PhpParser\Node\Stmt\ClassMethod|null|\PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall * @return \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|null|\PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall
*/ */
public function refactorWithScope(Node $node, Scope $scope) public function refactorWithScope(Node $node, Scope $scope)
{ {
if ($node instanceof ClassMethod) { if ($node instanceof ClassMethod || $node instanceof Function_) {
return $this->refactorClassMethod($node, $scope); return $this->refactorClassMethodOrFunction($node, $scope);
} }
if ($node instanceof New_) { if ($node instanceof New_) {
return $this->refactorNew($node, $scope); return $this->refactorNew($node, $scope);
} }
return $this->refactorMethodCall($node, $scope); return $this->refactorMethodCallOrFuncCall($node, $scope);
} }
private function refactorClassMethod(ClassMethod $classMethod, Scope $scope) : ?ClassMethod /**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $node
* @return \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|null
*/
private function refactorClassMethodOrFunction($node, Scope $scope)
{ {
if ($classMethod->params === []) { if ($node->params === []) {
return null; return null;
} }
if ($classMethod->getAttribute(self::HAS_SWAPPED_PARAMS, \false) === \true) { if ($node->getAttribute(self::HAS_SWAPPED_PARAMS, \false) === \true) {
return null; return null;
} }
$classMethodReflection = $this->reflectionResolver->resolveMethodReflectionFromClassMethod($classMethod, $scope); if ($node instanceof ClassMethod) {
if (!$classMethodReflection instanceof MethodReflection) { $reflection = $this->reflectionResolver->resolveMethodReflectionFromClassMethod($node, $scope);
} else {
$reflection = $this->reflectionResolver->resolveFunctionReflectionFromFunction($node, $scope);
}
if (!$reflection instanceof MethodReflection && !$reflection instanceof FunctionReflection) {
return null; return null;
} }
$expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($classMethodReflection, $classMethod, $scope); $expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($reflection, $node, $scope);
if ($expectedArgOrParamOrder === null) { if ($expectedArgOrParamOrder === null) {
return null; return null;
} }
$classMethod->params = $this->argumentSorter->sortArgsByExpectedParamOrder($classMethod->params, $expectedArgOrParamOrder); $node->params = $this->argumentSorter->sortArgsByExpectedParamOrder($node->params, $expectedArgOrParamOrder);
$classMethod->setAttribute(self::HAS_SWAPPED_PARAMS, \true); $node->setAttribute(self::HAS_SWAPPED_PARAMS, \true);
return $classMethod; return $node;
} }
private function refactorNew(New_ $new, Scope $scope) : ?New_ private function refactorNew(New_ $new, Scope $scope) : ?New_
{ {
@ -137,39 +149,46 @@ CODE_SAMPLE
return $new; return $new;
} }
/** /**
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall $methodCall * @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall $node
* @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|null * @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall|null
*/ */
private function refactorMethodCall($methodCall, Scope $scope) private function refactorMethodCallOrFuncCall($node, Scope $scope)
{ {
if ($methodCall->isFirstClassCallable()) { if ($node->isFirstClassCallable()) {
return null; return null;
} }
$methodReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($methodCall); $reflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node);
if (!$methodReflection instanceof MethodReflection) { if (!$reflection instanceof MethodReflection && !$reflection instanceof FunctionReflection) {
return null; return null;
} }
$expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($methodReflection, $methodCall, $scope); $expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($reflection, $node, $scope);
if ($expectedArgOrParamOrder === null) { if ($expectedArgOrParamOrder === null) {
return null; return null;
} }
$newArgs = $this->argumentSorter->sortArgsByExpectedParamOrder($methodCall->getArgs(), $expectedArgOrParamOrder); $newArgs = $this->argumentSorter->sortArgsByExpectedParamOrder($node->getArgs(), $expectedArgOrParamOrder);
if ($methodCall->args === $newArgs) { if ($node->args === $newArgs) {
return null; return null;
} }
$methodCall->args = $newArgs; $node->args = $newArgs;
return $methodCall; return $node;
} }
/** /**
* @return int[]|null * @return int[]|null
* @param \PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Expr\StaticCall $node * @param \PHPStan\Reflection\MethodReflection|\PHPStan\Reflection\FunctionReflection $reflection
* @param \PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall $node
*/ */
private function resolveExpectedArgParamOrderIfDifferent(MethodReflection $methodReflection, $node, Scope $scope) : ?array private function resolveExpectedArgParamOrderIfDifferent($reflection, $node, Scope $scope) : ?array
{ {
if ($this->vendorLocationDetector->detectMethodReflection($methodReflection)) { if ($reflection instanceof NativeFunctionReflection) {
return null; return null;
} }
$parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($methodReflection, $node, $scope); if ($reflection instanceof MethodReflection && $this->vendorLocationDetector->detectMethodReflection($reflection)) {
return null;
}
if ($reflection instanceof FunctionReflection && $this->vendorLocationDetector->detectFunctionReflection($reflection)) {
return null;
}
$parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($reflection, $node, $scope);
$expectedParameterReflections = $this->requireOptionalParamResolver->resolveFromParametersAcceptor($parametersAcceptor); $expectedParameterReflections = $this->requireOptionalParamResolver->resolveFromParametersAcceptor($parametersAcceptor);
if ($expectedParameterReflections === $parametersAcceptor->getParameters()) { if ($expectedParameterReflections === $parametersAcceptor->getParameters()) {
return null; return null;

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodeQuality\Rector\Concat; namespace Rector\CodeQuality\Rector\Concat;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\Concat; use PhpParser\Node\Expr\BinaryOp\Concat;
use PhpParser\Node\Scalar\String_; use PhpParser\Node\Scalar\String_;

View File

@ -6,10 +6,11 @@ namespace Rector\CodeQuality\Rector\Expression;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr; use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Ternary; use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_; use PhpParser\Node\Stmt\If_;
use PHPStan\Analyser\Scope; use PHPStan\Analyser\Scope;
use Rector\DeadCode\SideEffect\SideEffectNodeDetector; use Rector\NodeAnalyzer\ExprAnalyzer;
use Rector\Rector\AbstractScopeAwareRector; use Rector\Rector\AbstractScopeAwareRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -20,12 +21,12 @@ final class TernaryFalseExpressionToIfRector extends AbstractScopeAwareRector
{ {
/** /**
* @readonly * @readonly
* @var \Rector\DeadCode\SideEffect\SideEffectNodeDetector * @var \Rector\NodeAnalyzer\ExprAnalyzer
*/ */
private $sideEffectNodeDetector; private $exprAnalyzer;
public function __construct(SideEffectNodeDetector $sideEffectNodeDetector) public function __construct(ExprAnalyzer $exprAnalyzer)
{ {
$this->sideEffectNodeDetector = $sideEffectNodeDetector; $this->exprAnalyzer = $exprAnalyzer;
} }
public function getRuleDefinition() : RuleDefinition public function getRuleDefinition() : RuleDefinition
{ {
@ -70,7 +71,7 @@ CODE_SAMPLE
if (!$ternary->if instanceof Expr) { if (!$ternary->if instanceof Expr) {
return null; return null;
} }
if ($this->sideEffectNodeDetector->detect($ternary->else, $scope) || $this->sideEffectNodeDetector->detectCallExpr($ternary->else, $scope)) { if (!$ternary->else instanceof Variable && $this->exprAnalyzer->isDynamicExpr($ternary->else)) {
return null; return null;
} }
return new If_($ternary->cond, ['stmts' => [new Expression($ternary->if)]]); return new If_($ternary->cond, ['stmts' => [new Expression($ternary->if)]]);

View File

@ -13,13 +13,14 @@ use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt; use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\For_; use PhpParser\Node\Stmt\For_;
use Rector\Rector\AbstractRector; use PHPStan\Analyser\Scope;
use Rector\Rector\AbstractScopeAwareRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/** /**
* @see \Rector\Tests\CodeQuality\Rector\For_\ForRepeatedCountToOwnVariableRector\ForRepeatedCountToOwnVariableRectorTest * @see \Rector\Tests\CodeQuality\Rector\For_\ForRepeatedCountToOwnVariableRector\ForRepeatedCountToOwnVariableRectorTest
*/ */
final class ForRepeatedCountToOwnVariableRector extends AbstractRector final class ForRepeatedCountToOwnVariableRector extends AbstractScopeAwareRector
{ {
/** /**
* @var string * @var string
@ -63,8 +64,11 @@ CODE_SAMPLE
* @param For_ $node * @param For_ $node
* @return Stmt[]|null * @return Stmt[]|null
*/ */
public function refactor(Node $node) : ?array public function refactorWithScope(Node $node, Scope $scope) : ?array
{ {
if ($scope->hasVariableType(self::COUNTER_NAME)->yes()) {
return null;
}
$countInCond = null; $countInCond = null;
$counterVariable = new Variable(self::COUNTER_NAME); $counterVariable = new Variable(self::COUNTER_NAME);
foreach ($node->cond as $condExpr) { foreach ($node->cond as $condExpr) {

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodeQuality\Rector\FuncCall; namespace Rector\CodeQuality\Rector\FuncCall;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Scalar\String_; use PhpParser\Node\Scalar\String_;
use Rector\NodeNameResolver\Regex\RegexPatternDetector; use Rector\NodeNameResolver\Regex\RegexPatternDetector;

View File

@ -3,9 +3,11 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodeQuality\Rector\FuncCall; namespace Rector\CodeQuality\Rector\FuncCall;
use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name; use PhpParser\Node\Name;
use PhpParser\Node\Scalar\String_;
use Rector\Rector\AbstractRector; use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -14,6 +16,11 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/ */
final class SimplifyStrposLowerRector extends AbstractRector final class SimplifyStrposLowerRector extends AbstractRector
{ {
/**
* @var string
* @see https://regex101.com/r/Jokjt8/1
*/
private const UPPERCASE_REGEX = '#[A-Z]#';
public function getRuleDefinition() : RuleDefinition public function getRuleDefinition() : RuleDefinition
{ {
return new RuleDefinition('Simplify strpos(strtolower(), "...") calls', [new CodeSample('strpos(strtolower($var), "...")', 'stripos($var, "...")')]); return new RuleDefinition('Simplify strpos(strtolower(), "...") calls', [new CodeSample('strpos(strtolower($var), "...")', 'stripos($var, "...")')]);
@ -36,10 +43,11 @@ final class SimplifyStrposLowerRector extends AbstractRector
if ($node->isFirstClassCallable()) { if ($node->isFirstClassCallable()) {
return null; return null;
} }
if (!isset($node->getArgs()[0])) { $args = $node->getArgs();
if (!isset($args[0], $args[1])) {
return null; return null;
} }
$firstArg = $node->getArgs()[0]; $firstArg = $args[0];
if (!$firstArg->value instanceof FuncCall) { if (!$firstArg->value instanceof FuncCall) {
return null; return null;
} }
@ -48,6 +56,13 @@ final class SimplifyStrposLowerRector extends AbstractRector
if (!$this->isName($innerFuncCall, 'strtolower')) { if (!$this->isName($innerFuncCall, 'strtolower')) {
return null; return null;
} }
$secondArg = $args[1];
if (!$secondArg->value instanceof String_) {
return null;
}
if (Strings::match($secondArg->value->value, self::UPPERCASE_REGEX) !== null) {
return null;
}
// pop 1 level up // pop 1 level up
$node->args[0] = $innerFuncCall->getArgs()[0]; $node->args[0] = $innerFuncCall->getArgs()[0];
$node->name = new Name('stripos'); $node->name = new Name('stripos');

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodeQuality\Rector\Include_; namespace Rector\CodeQuality\Rector\Include_;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\Concat; use PhpParser\Node\Expr\BinaryOp\Concat;
use PhpParser\Node\Expr\Include_; use PhpParser\Node\Expr\Include_;

View File

@ -53,6 +53,6 @@ final class SimplifyTautologyTernaryRector extends AbstractRector
if (!$twoNodeMatch instanceof TwoNodeMatch) { if (!$twoNodeMatch instanceof TwoNodeMatch) {
return null; return null;
} }
return $node->if; return $node->cond instanceof NotIdentical ? $node->if : $node->else;
} }
} }

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodingStyle\Application; namespace Rector\CodingStyle\Application;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node\Name; use PhpParser\Node\Name;
use PhpParser\Node\Stmt; use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Declare_; use PhpParser\Node\Stmt\Declare_;

View File

@ -3,11 +3,10 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodingStyle\ClassNameImport\ClassNameImportSkipVoter; namespace Rector\CodingStyle\ClassNameImport\ClassNameImportSkipVoter;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node; use PhpParser\Node;
use Rector\CodingStyle\ClassNameImport\ShortNameResolver; use Rector\CodingStyle\ClassNameImport\ShortNameResolver;
use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface; use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface;
use Rector\Configuration\RenamedClassesDataCollector;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType; use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Rector\ValueObject\Application\File; use Rector\ValueObject\Application\File;
/** /**
@ -26,15 +25,9 @@ final class FullyQualifiedNameClassNameImportSkipVoter implements ClassNameImpor
* @var \Rector\CodingStyle\ClassNameImport\ShortNameResolver * @var \Rector\CodingStyle\ClassNameImport\ShortNameResolver
*/ */
private $shortNameResolver; private $shortNameResolver;
/** public function __construct(ShortNameResolver $shortNameResolver)
* @readonly
* @var \Rector\Configuration\RenamedClassesDataCollector
*/
private $renamedClassesDataCollector;
public function __construct(ShortNameResolver $shortNameResolver, RenamedClassesDataCollector $renamedClassesDataCollector)
{ {
$this->shortNameResolver = $shortNameResolver; $this->shortNameResolver = $shortNameResolver;
$this->renamedClassesDataCollector = $renamedClassesDataCollector;
} }
public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool
{ {
@ -43,7 +36,6 @@ final class FullyQualifiedNameClassNameImportSkipVoter implements ClassNameImpor
$shortNamesToFullyQualifiedNames = $this->shortNameResolver->resolveFromFile($file); $shortNamesToFullyQualifiedNames = $this->shortNameResolver->resolveFromFile($file);
$fullyQualifiedObjectTypeShortName = $fullyQualifiedObjectType->getShortName(); $fullyQualifiedObjectTypeShortName = $fullyQualifiedObjectType->getShortName();
$className = $fullyQualifiedObjectType->getClassName(); $className = $fullyQualifiedObjectType->getClassName();
$removedUses = $this->renamedClassesDataCollector->getOldClasses();
foreach ($shortNamesToFullyQualifiedNames as $shortName => $fullyQualifiedName) { foreach ($shortNamesToFullyQualifiedNames as $shortName => $fullyQualifiedName) {
if ($fullyQualifiedObjectTypeShortName !== $shortName) { if ($fullyQualifiedObjectTypeShortName !== $shortName) {
$shortName = $this->cleanShortName($shortName); $shortName = $this->cleanShortName($shortName);
@ -52,10 +44,7 @@ final class FullyQualifiedNameClassNameImportSkipVoter implements ClassNameImpor
continue; continue;
} }
$fullyQualifiedName = \ltrim($fullyQualifiedName, '\\'); $fullyQualifiedName = \ltrim($fullyQualifiedName, '\\');
if ($className === $fullyQualifiedName) { return $className !== $fullyQualifiedName;
return \false;
}
return !\in_array($fullyQualifiedName, $removedUses, \true);
} }
return \false; return \false;
} }

View File

@ -5,7 +5,6 @@ namespace Rector\CodingStyle\ClassNameImport\ClassNameImportSkipVoter;
use PhpParser\Node; use PhpParser\Node;
use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface; use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface;
use Rector\Configuration\RenamedClassesDataCollector;
use Rector\PostRector\Collector\UseNodesToAddCollector; use Rector\PostRector\Collector\UseNodesToAddCollector;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType; use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Rector\ValueObject\Application\File; use Rector\ValueObject\Application\File;
@ -23,24 +22,14 @@ final class UsesClassNameImportSkipVoter implements ClassNameImportSkipVoterInte
* @var \Rector\PostRector\Collector\UseNodesToAddCollector * @var \Rector\PostRector\Collector\UseNodesToAddCollector
*/ */
private $useNodesToAddCollector; private $useNodesToAddCollector;
/** public function __construct(UseNodesToAddCollector $useNodesToAddCollector)
* @readonly
* @var \Rector\Configuration\RenamedClassesDataCollector
*/
private $renamedClassesDataCollector;
public function __construct(UseNodesToAddCollector $useNodesToAddCollector, RenamedClassesDataCollector $renamedClassesDataCollector)
{ {
$this->useNodesToAddCollector = $useNodesToAddCollector; $this->useNodesToAddCollector = $useNodesToAddCollector;
$this->renamedClassesDataCollector = $renamedClassesDataCollector;
} }
public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool
{ {
$useImportTypes = $this->useNodesToAddCollector->getUseImportTypesByNode($file, $node); $useImportTypes = $this->useNodesToAddCollector->getUseImportTypesByNode($file);
foreach ($useImportTypes as $useImportType) { foreach ($useImportTypes as $useImportType) {
// if the class is renamed, the use import is no longer blocker
if ($this->renamedClassesDataCollector->hasOldClass($useImportType->getClassName())) {
continue;
}
if (!$useImportType->equals($fullyQualifiedObjectType) && $useImportType->areShortNamesEqual($fullyQualifiedObjectType)) { if (!$useImportType->equals($fullyQualifiedObjectType) && $useImportType->areShortNamesEqual($fullyQualifiedObjectType)) {
return \true; return \true;
} }

View File

@ -3,7 +3,6 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodingStyle\ClassNameImport; namespace Rector\CodingStyle\ClassNameImport;
use RectorPrefix202403\Nette\Utils\Reflection;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Identifier; use PhpParser\Node\Identifier;
use PhpParser\Node\Name; use PhpParser\Node\Name;
@ -12,8 +11,6 @@ use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Namespace_; use PhpParser\Node\Stmt\Namespace_;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ReflectionProvider;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\CodingStyle\NodeAnalyzer\UseImportNameMatcher; use Rector\CodingStyle\NodeAnalyzer\UseImportNameMatcher;
@ -24,7 +21,6 @@ use Rector\PhpDocParser\PhpDocParser\PhpDocNodeTraverser;
use Rector\PhpParser\Node\BetterNodeFinder; use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace; use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
use Rector\ValueObject\Application\File; use Rector\ValueObject\Application\File;
use ReflectionClass;
/** /**
* @see \Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\ShortNameResolverTest * @see \Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\ShortNameResolverTest
*/ */
@ -40,11 +36,6 @@ final class ShortNameResolver
* @var \Rector\NodeNameResolver\NodeNameResolver * @var \Rector\NodeNameResolver\NodeNameResolver
*/ */
private $nodeNameResolver; private $nodeNameResolver;
/**
* @readonly
* @var \PHPStan\Reflection\ReflectionProvider
*/
private $reflectionProvider;
/** /**
* @readonly * @readonly
* @var \Rector\PhpParser\Node\BetterNodeFinder * @var \Rector\PhpParser\Node\BetterNodeFinder
@ -64,11 +55,10 @@ final class ShortNameResolver
* @var array<string, string[]> * @var array<string, string[]>
*/ */
private $shortNamesByFilePath = []; private $shortNamesByFilePath = [];
public function __construct(SimpleCallableNodeTraverser $simpleCallableNodeTraverser, NodeNameResolver $nodeNameResolver, ReflectionProvider $reflectionProvider, BetterNodeFinder $betterNodeFinder, UseImportNameMatcher $useImportNameMatcher, PhpDocInfoFactory $phpDocInfoFactory) public function __construct(SimpleCallableNodeTraverser $simpleCallableNodeTraverser, NodeNameResolver $nodeNameResolver, BetterNodeFinder $betterNodeFinder, UseImportNameMatcher $useImportNameMatcher, PhpDocInfoFactory $phpDocInfoFactory)
{ {
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser; $this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
$this->nodeNameResolver = $nodeNameResolver; $this->nodeNameResolver = $nodeNameResolver;
$this->reflectionProvider = $reflectionProvider;
$this->betterNodeFinder = $betterNodeFinder; $this->betterNodeFinder = $betterNodeFinder;
$this->useImportNameMatcher = $useImportNameMatcher; $this->useImportNameMatcher = $useImportNameMatcher;
$this->phpDocInfoFactory = $phpDocInfoFactory; $this->phpDocInfoFactory = $phpDocInfoFactory;
@ -152,7 +142,6 @@ final class ShortNameResolver
*/ */
private function resolveFromStmtsDocBlocks(array $stmts) : array private function resolveFromStmtsDocBlocks(array $stmts) : array
{ {
$classReflection = $this->resolveClassReflection($stmts);
$shortNames = []; $shortNames = [];
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($stmts, function (Node $node) use(&$shortNames) { $this->simpleCallableNodeTraverser->traverseNodesWithCallable($stmts, function (Node $node) use(&$shortNames) {
// speed up for nodes that are // speed up for nodes that are
@ -176,42 +165,22 @@ final class ShortNameResolver
}); });
return null; return null;
}); });
return $this->fqnizeShortNames($shortNames, $classReflection, $stmts); return $this->fqnizeShortNames($shortNames, $stmts);
}
/**
* @param Node[] $stmts
*/
private function resolveClassReflection(array $stmts) : ?ClassReflection
{
$firstClassLike = $this->betterNodeFinder->findFirstInstanceOf($stmts, ClassLike::class);
if (!$firstClassLike instanceof ClassLike) {
return null;
}
$className = (string) $this->nodeNameResolver->getName($firstClassLike);
if (!$this->reflectionProvider->hasClass($className)) {
return null;
}
return $this->reflectionProvider->getClass($className);
} }
/** /**
* @param string[] $shortNames * @param string[] $shortNames
* @param Stmt[] $stmts * @param Stmt[] $stmts
* @return array<string, string> * @return array<string, string>
*/ */
private function fqnizeShortNames(array $shortNames, ?ClassReflection $classReflection, array $stmts) : array private function fqnizeShortNames(array $shortNames, array $stmts) : array
{ {
$shortNamesToFullyQualifiedNames = []; $shortNamesToFullyQualifiedNames = [];
$nativeReflectionClass = $classReflection instanceof ClassReflection && !$classReflection->isAnonymous() ? $classReflection->getNativeReflection() : null;
foreach ($shortNames as $shortName) { foreach ($shortNames as $shortName) {
$stmtsMatchedName = $this->useImportNameMatcher->matchNameWithStmts($shortName, $stmts); $stmtsMatchedName = $this->useImportNameMatcher->matchNameWithStmts($shortName, $stmts);
if ($nativeReflectionClass instanceof ReflectionClass) { if ($stmtsMatchedName == null) {
$fullyQualifiedName = Reflection::expandClassName($shortName, $nativeReflectionClass); continue;
} elseif (\is_string($stmtsMatchedName)) {
$fullyQualifiedName = $stmtsMatchedName;
} else {
$fullyQualifiedName = $shortName;
} }
$shortNamesToFullyQualifiedNames[$shortName] = $fullyQualifiedName; $shortNamesToFullyQualifiedNames[$shortName] = $stmtsMatchedName;
} }
return $shortNamesToFullyQualifiedNames; return $shortNamesToFullyQualifiedNames;
} }

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodingStyle\Naming; namespace Rector\CodingStyle\Naming;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node\Identifier; use PhpParser\Node\Identifier;
use PhpParser\Node\Name; use PhpParser\Node\Name;
use PhpParser\Node\Stmt\ClassLike; use PhpParser\Node\Stmt\ClassLike;

View File

@ -10,7 +10,7 @@ use Rector\Configuration\Option;
use Rector\Configuration\Parameter\SimpleParameterProvider; use Rector\Configuration\Parameter\SimpleParameterProvider;
use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Collector\UseNodesToAddCollector; use Rector\PostRector\Collector\UseNodesToAddCollector;
use Rector\StaticTypeMapper\StaticTypeMapper; use Rector\StaticTypeMapper\PhpParser\FullyQualifiedNodeMapper;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType; use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Rector\ValueObject\Application\File; use Rector\ValueObject\Application\File;
final class NameImporter final class NameImporter
@ -22,18 +22,18 @@ final class NameImporter
private $classNameImportSkipper; private $classNameImportSkipper;
/** /**
* @readonly * @readonly
* @var \Rector\StaticTypeMapper\StaticTypeMapper * @var \Rector\StaticTypeMapper\PhpParser\FullyQualifiedNodeMapper
*/ */
private $staticTypeMapper; private $fullyQualifiedNodeMapper;
/** /**
* @readonly * @readonly
* @var \Rector\PostRector\Collector\UseNodesToAddCollector * @var \Rector\PostRector\Collector\UseNodesToAddCollector
*/ */
private $useNodesToAddCollector; private $useNodesToAddCollector;
public function __construct(ClassNameImportSkipper $classNameImportSkipper, StaticTypeMapper $staticTypeMapper, UseNodesToAddCollector $useNodesToAddCollector) public function __construct(ClassNameImportSkipper $classNameImportSkipper, FullyQualifiedNodeMapper $fullyQualifiedNodeMapper, UseNodesToAddCollector $useNodesToAddCollector)
{ {
$this->classNameImportSkipper = $classNameImportSkipper; $this->classNameImportSkipper = $classNameImportSkipper;
$this->staticTypeMapper = $staticTypeMapper; $this->fullyQualifiedNodeMapper = $fullyQualifiedNodeMapper;
$this->useNodesToAddCollector = $useNodesToAddCollector; $this->useNodesToAddCollector = $useNodesToAddCollector;
} }
public function importName(FullyQualified $fullyQualified, File $file) : ?Name public function importName(FullyQualified $fullyQualified, File $file) : ?Name
@ -41,7 +41,7 @@ final class NameImporter
if ($this->shouldSkipName($fullyQualified)) { if ($this->shouldSkipName($fullyQualified)) {
return null; return null;
} }
$staticType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($fullyQualified); $staticType = $this->fullyQualifiedNodeMapper->mapToPHPStan($fullyQualified);
if (!$staticType instanceof FullyQualifiedObjectType) { if (!$staticType instanceof FullyQualifiedObjectType) {
return null; return null;
} }

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodingStyle\NodeAnalyzer; namespace Rector\CodingStyle\NodeAnalyzer;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node\Identifier; use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt; use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\GroupUse; use PhpParser\Node\Stmt\GroupUse;

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodingStyle\Rector\Catch_; namespace Rector\CodingStyle\Rector\Catch_;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Closure; use PhpParser\Node\Expr\Closure;

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodingStyle\Rector\Encapsed; namespace Rector\CodingStyle\Rector\Encapsed;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Arg; use PhpParser\Node\Arg;
use PhpParser\Node\Expr; use PhpParser\Node\Expr;

View File

@ -123,7 +123,7 @@ CODE_SAMPLE
} }
/** /**
* @param int|float $rangeLine * @param int|float $rangeLine
* @return int|float * @return float|int
*/ */
private function resolveRangeLineFromComment($rangeLine, int $line, int $endLine, Stmt $nextStmt) private function resolveRangeLineFromComment($rangeLine, int $line, int $endLine, Stmt $nextStmt)
{ {

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodingStyle\Rector\Stmt; namespace Rector\CodingStyle\Rector\Stmt;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Identifier; use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\Namespace_; use PhpParser\Node\Stmt\Namespace_;

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodingStyle\Rector\String_; namespace Rector\CodingStyle\Rector\String_;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr\ClassConstFetch; use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Name\FullyQualified;

View File

@ -3,6 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\CodingStyle\Reflection; namespace Rector\CodingStyle\Reflection;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\MethodReflection; use PHPStan\Reflection\MethodReflection;
use Rector\FileSystem\FilePathHelper; use Rector\FileSystem\FilePathHelper;
final class VendorLocationDetector final class VendorLocationDetector
@ -20,6 +21,15 @@ final class VendorLocationDetector
{ {
$declaringClassReflection = $methodReflection->getDeclaringClass(); $declaringClassReflection = $methodReflection->getDeclaringClass();
$fileName = $declaringClassReflection->getFileName(); $fileName = $declaringClassReflection->getFileName();
return $this->detect($fileName);
}
public function detectFunctionReflection(FunctionReflection $functionReflection) : bool
{
$fileName = $functionReflection->getFileName();
return $this->detect($fileName);
}
private function detect(?string $fileName = null) : bool
{
// probably internal // probably internal
if ($fileName === null) { if ($fileName === null) {
return \false; return \false;

View File

@ -4,6 +4,7 @@ declare (strict_types=1);
namespace Rector\DeadCode\NodeAnalyzer; namespace Rector\DeadCode\NodeAnalyzer;
use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\NullsafeMethodCall;
use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier; use PhpParser\Node\Identifier;
use PhpParser\Node\Name; use PhpParser\Node\Name;
@ -29,7 +30,7 @@ final class CallCollectionAnalyzer
$this->nodeNameResolver = $nodeNameResolver; $this->nodeNameResolver = $nodeNameResolver;
} }
/** /**
* @param StaticCall[]|MethodCall[] $calls * @param StaticCall[]|MethodCall[]|NullsafeMethodCall[] $calls
*/ */
public function isExists(array $calls, string $classMethodName, string $className) : bool public function isExists(array $calls, string $classMethodName, string $className) : bool
{ {
@ -52,14 +53,14 @@ final class CallCollectionAnalyzer
return \false; return \false;
} }
/** /**
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall $call * @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\NullsafeMethodCall $call
*/ */
private function isSelfStatic($call) : bool private function isSelfStatic($call) : bool
{ {
return $call instanceof StaticCall && $call->class instanceof Name && \in_array($call->class->toString(), [ObjectReference::SELF, ObjectReference::STATIC], \true); return $call instanceof StaticCall && $call->class instanceof Name && \in_array($call->class->toString(), [ObjectReference::SELF, ObjectReference::STATIC], \true);
} }
/** /**
* @param \PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\MethodCall $call * @param \PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\NullsafeMethodCall $call
*/ */
private function shouldSkip($call, string $classMethodName) : bool private function shouldSkip($call, string $classMethodName) : bool
{ {

View File

@ -9,6 +9,7 @@ use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem; use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\CallLike; use PhpParser\Node\Expr\CallLike;
use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\NullsafeMethodCall;
use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name; use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\Class_;
@ -88,11 +89,15 @@ final class IsClassMethodUsedAnalyzer
if ($this->isClassMethodCalledInLocalMethodCall($class, $classMethodName)) { if ($this->isClassMethodCalledInLocalMethodCall($class, $classMethodName)) {
return \true; return \true;
} }
// 2. direct static calls // 2. direct null-safe calls
if ($this->isClassMethodCalledInLocalNullsafeMethodCall($class, $classMethodName)) {
return \true;
}
// 3. direct static calls
if ($this->isClassMethodUsedInLocalStaticCall($class, $classMethodName)) { if ($this->isClassMethodUsedInLocalStaticCall($class, $classMethodName)) {
return \true; return \true;
} }
// 3. magic array calls! // 4. magic array calls!
if ($this->isClassMethodCalledInLocalArrayCall($class, $classMethod, $scope)) { if ($this->isClassMethodCalledInLocalArrayCall($class, $classMethod, $scope)) {
return \true; return \true;
} }
@ -113,6 +118,13 @@ final class IsClassMethodUsedAnalyzer
$methodCalls = $this->betterNodeFinder->findInstanceOf($class, MethodCall::class); $methodCalls = $this->betterNodeFinder->findInstanceOf($class, MethodCall::class);
return $this->callCollectionAnalyzer->isExists($methodCalls, $classMethodName, $className); return $this->callCollectionAnalyzer->isExists($methodCalls, $classMethodName, $className);
} }
private function isClassMethodCalledInLocalNullsafeMethodCall(Class_ $class, string $classMethodName) : bool
{
$className = (string) $this->nodeNameResolver->getName($class);
/** @var NullsafeMethodCall[] $methodCalls */
$methodCalls = $this->betterNodeFinder->findInstanceOf($class, NullsafeMethodCall::class);
return $this->callCollectionAnalyzer->isExists($methodCalls, $classMethodName, $className);
}
private function isInArrayMap(Class_ $class, Array_ $array) : bool private function isInArrayMap(Class_ $class, Array_ $array) : bool
{ {
if (!$array->getAttribute(ArrayMapArgVisitor::ATTRIBUTE_NAME) instanceof Arg) { if (!$array->getAttribute(ArrayMapArgVisitor::ATTRIBUTE_NAME) instanceof Arg) {
@ -134,11 +146,12 @@ final class IsClassMethodUsedAnalyzer
{ {
/** @var Array_[] $arrays */ /** @var Array_[] $arrays */
$arrays = $this->betterNodeFinder->findInstanceOf($class, Array_::class); $arrays = $this->betterNodeFinder->findInstanceOf($class, Array_::class);
$classMethodName = $this->nodeNameResolver->getName($classMethod);
foreach ($arrays as $array) { foreach ($arrays as $array) {
if ($this->isInArrayMap($class, $array)) { if ($this->isInArrayMap($class, $array)) {
return \true; return \true;
} }
$arrayCallable = $this->arrayCallableMethodMatcher->match($array, $scope); $arrayCallable = $this->arrayCallableMethodMatcher->match($array, $scope, $classMethodName);
if ($arrayCallable instanceof ArrayCallableDynamicMethod) { if ($arrayCallable instanceof ArrayCallableDynamicMethod) {
return \true; return \true;
} }

View File

@ -5,6 +5,7 @@ namespace Rector\DeadCode\NodeAnalyzer;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr; use PhpParser\Node\Expr;
use PhpParser\Node\Expr\NullsafePropertyFetch;
use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch; use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\Class_;
@ -24,7 +25,7 @@ final class PropertyWriteonlyAnalyzer
public function hasClassDynamicPropertyNames(Class_ $class) : bool public function hasClassDynamicPropertyNames(Class_ $class) : bool
{ {
return (bool) $this->betterNodeFinder->findFirst($class, static function (Node $node) : bool { return (bool) $this->betterNodeFinder->findFirst($class, static function (Node $node) : bool {
if (!$node instanceof PropertyFetch) { if (!$node instanceof PropertyFetch && !$node instanceof NullsafePropertyFetch) {
return \false; return \false;
} }
// has dynamic name - could be anything // has dynamic name - could be anything
@ -34,7 +35,7 @@ final class PropertyWriteonlyAnalyzer
/** /**
* The property fetches are always only assigned to, nothing else * The property fetches are always only assigned to, nothing else
* *
* @param array<PropertyFetch|StaticPropertyFetch> $propertyFetches * @param array<PropertyFetch|StaticPropertyFetch|NullsafePropertyFetch> $propertyFetches
*/ */
public function arePropertyFetchesExclusivelyBeingAssignedTo(array $propertyFetches) : bool public function arePropertyFetchesExclusivelyBeingAssignedTo(array $propertyFetches) : bool
{ {

View File

@ -0,0 +1,66 @@
<?php
declare (strict_types=1);
namespace Rector\DeadCode\NodeAnalyzer;
use PhpParser\Node;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use PhpParser\Node\Expr\Instanceof_;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Expr\Variable;
use PHPStan\Reflection\ClassReflection;
use Rector\NodeAnalyzer\ExprAnalyzer;
use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\Reflection\ReflectionResolver;
final class SafeLeftTypeBooleanAndOrAnalyzer
{
/**
* @readonly
* @var \Rector\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @readonly
* @var \Rector\NodeAnalyzer\ExprAnalyzer
*/
private $exprAnalyzer;
/**
* @readonly
* @var \Rector\Reflection\ReflectionResolver
*/
private $reflectionResolver;
public function __construct(BetterNodeFinder $betterNodeFinder, ExprAnalyzer $exprAnalyzer, ReflectionResolver $reflectionResolver)
{
$this->betterNodeFinder = $betterNodeFinder;
$this->exprAnalyzer = $exprAnalyzer;
$this->reflectionResolver = $reflectionResolver;
}
/**
* @param \PhpParser\Node\Expr\BinaryOp\BooleanAnd|\PhpParser\Node\Expr\BinaryOp\BooleanOr $booleanAnd
*/
public function isSafe($booleanAnd) : bool
{
$hasNonTypedFromParam = (bool) $this->betterNodeFinder->findFirst($booleanAnd->left, function (Node $node) : bool {
return $node instanceof Variable && $this->exprAnalyzer->isNonTypedFromParam($node);
});
if ($hasNonTypedFromParam) {
return \false;
}
$hasPropertyFetchOrArrayDimFetch = (bool) $this->betterNodeFinder->findFirst($booleanAnd->left, static function (Node $node) : bool {
return $node instanceof PropertyFetch || $node instanceof StaticPropertyFetch || $node instanceof ArrayDimFetch;
});
// get type from Property and ArrayDimFetch is unreliable
if ($hasPropertyFetchOrArrayDimFetch) {
return \false;
}
// skip trait this
$classReflection = $this->reflectionResolver->resolveClassReflection($booleanAnd);
if ($classReflection instanceof ClassReflection && $classReflection->isTrait()) {
return !$booleanAnd->left instanceof Instanceof_;
}
return \true;
}
}

View File

@ -0,0 +1,44 @@
<?php
declare (strict_types=1);
namespace Rector\DeadCode\NodeManipulator;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\NodeAnalyzer\ParamAnalyzer;
use Rector\Removing\NodeManipulator\ComplexNodeRemover;
final class ClassMethodParamRemover
{
/**
* @readonly
* @var \Rector\NodeAnalyzer\ParamAnalyzer
*/
private $paramAnalyzer;
/**
* @readonly
* @var \Rector\Removing\NodeManipulator\ComplexNodeRemover
*/
private $complexNodeRemover;
public function __construct(ParamAnalyzer $paramAnalyzer, ComplexNodeRemover $complexNodeRemover)
{
$this->paramAnalyzer = $paramAnalyzer;
$this->complexNodeRemover = $complexNodeRemover;
}
public function processRemoveParams(ClassMethod $classMethod) : ?ClassMethod
{
$paramKeysToBeRemoved = [];
foreach ($classMethod->params as $key => $param) {
if ($this->paramAnalyzer->isParamUsedInClassMethod($classMethod, $param)) {
continue;
}
$paramKeysToBeRemoved[] = $key;
}
if ($paramKeysToBeRemoved === []) {
return null;
}
$removedParamKeys = $this->complexNodeRemover->processRemoveParamWithKeys($classMethod, $paramKeysToBeRemoved);
if ($removedParamKeys !== []) {
return $classMethod;
}
return null;
}
}

View File

@ -10,6 +10,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode; use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode;
use Rector\DeadCode\PhpDoc\Guard\StandaloneTypeRemovalGuard;
use Rector\DeadCode\TypeNodeAnalyzer\GenericTypeNodeAnalyzer; use Rector\DeadCode\TypeNodeAnalyzer\GenericTypeNodeAnalyzer;
use Rector\DeadCode\TypeNodeAnalyzer\MixedArrayTypeNodeAnalyzer; use Rector\DeadCode\TypeNodeAnalyzer\MixedArrayTypeNodeAnalyzer;
use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeNameResolver\NodeNameResolver;
@ -47,7 +48,12 @@ final class DeadParamTagValueNodeAnalyzer
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger * @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger
*/ */
private $phpDocTypeChanger; private $phpDocTypeChanger;
public function __construct(NodeNameResolver $nodeNameResolver, TypeComparator $typeComparator, GenericTypeNodeAnalyzer $genericTypeNodeAnalyzer, MixedArrayTypeNodeAnalyzer $mixedArrayTypeNodeAnalyzer, ParamAnalyzer $paramAnalyzer, PhpDocTypeChanger $phpDocTypeChanger) /**
* @readonly
* @var \Rector\DeadCode\PhpDoc\Guard\StandaloneTypeRemovalGuard
*/
private $standaloneTypeRemovalGuard;
public function __construct(NodeNameResolver $nodeNameResolver, TypeComparator $typeComparator, GenericTypeNodeAnalyzer $genericTypeNodeAnalyzer, MixedArrayTypeNodeAnalyzer $mixedArrayTypeNodeAnalyzer, ParamAnalyzer $paramAnalyzer, PhpDocTypeChanger $phpDocTypeChanger, StandaloneTypeRemovalGuard $standaloneTypeRemovalGuard)
{ {
$this->nodeNameResolver = $nodeNameResolver; $this->nodeNameResolver = $nodeNameResolver;
$this->typeComparator = $typeComparator; $this->typeComparator = $typeComparator;
@ -55,6 +61,7 @@ final class DeadParamTagValueNodeAnalyzer
$this->mixedArrayTypeNodeAnalyzer = $mixedArrayTypeNodeAnalyzer; $this->mixedArrayTypeNodeAnalyzer = $mixedArrayTypeNodeAnalyzer;
$this->paramAnalyzer = $paramAnalyzer; $this->paramAnalyzer = $paramAnalyzer;
$this->phpDocTypeChanger = $phpDocTypeChanger; $this->phpDocTypeChanger = $phpDocTypeChanger;
$this->standaloneTypeRemovalGuard = $standaloneTypeRemovalGuard;
} }
public function isDead(ParamTagValueNode $paramTagValueNode, FunctionLike $functionLike) : bool public function isDead(ParamTagValueNode $paramTagValueNode, FunctionLike $functionLike) : bool
{ {
@ -78,11 +85,15 @@ final class DeadParamTagValueNodeAnalyzer
return \false; return \false;
} }
if (!$paramTagValueNode->type instanceof BracketsAwareUnionTypeNode) { if (!$paramTagValueNode->type instanceof BracketsAwareUnionTypeNode) {
return \true; return $this->standaloneTypeRemovalGuard->isLegal($paramTagValueNode->type, $param->type);
} }
if ($this->mixedArrayTypeNodeAnalyzer->hasMixedArrayType($paramTagValueNode->type)) { return $this->isAllowedBracketAwareUnion($paramTagValueNode->type);
}
private function isAllowedBracketAwareUnion(BracketsAwareUnionTypeNode $bracketsAwareUnionTypeNode) : bool
{
if ($this->mixedArrayTypeNodeAnalyzer->hasMixedArrayType($bracketsAwareUnionTypeNode)) {
return \false; return \false;
} }
return !$this->genericTypeNodeAnalyzer->hasGenericType($paramTagValueNode->type); return !$this->genericTypeNodeAnalyzer->hasGenericType($bracketsAwareUnionTypeNode);
} }
} }

View File

@ -7,7 +7,7 @@ use PhpParser\Node\FunctionLike;
use PHPStan\PhpDocParser\Ast\Node; use PHPStan\PhpDocParser\Ast\Node;
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode; use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\Comments\NodeDocBlock\DocBlockUpdater; use Rector\Comments\NodeDocBlock\DocBlockUpdater;
use Rector\DeadCode\PhpDoc\DeadParamTagValueNodeAnalyzer; use Rector\DeadCode\PhpDoc\DeadParamTagValueNodeAnalyzer;
@ -29,11 +29,11 @@ final class ParamTagRemover
$this->deadParamTagValueNodeAnalyzer = $deadParamTagValueNodeAnalyzer; $this->deadParamTagValueNodeAnalyzer = $deadParamTagValueNodeAnalyzer;
$this->docBlockUpdater = $docBlockUpdater; $this->docBlockUpdater = $docBlockUpdater;
} }
public function removeParamTagsIfUseless(PhpDocInfo $phpDocInfo, FunctionLike $functionLike) : bool public function removeParamTagsIfUseless(PhpDocInfo $phpDocInfo, FunctionLike $functionLike, ?Type $type = null) : bool
{ {
$hasChanged = \false; $hasChanged = \false;
$phpDocNodeTraverser = new PhpDocNodeTraverser(); $phpDocNodeTraverser = new PhpDocNodeTraverser();
$phpDocNodeTraverser->traverseWithCallable($phpDocInfo->getPhpDocNode(), '', function (Node $docNode) use($functionLike, &$hasChanged) : ?int { $phpDocNodeTraverser->traverseWithCallable($phpDocInfo->getPhpDocNode(), '', function (Node $docNode) use($functionLike, &$hasChanged, $type, $phpDocInfo) : ?int {
if (!$docNode instanceof PhpDocTagNode) { if (!$docNode instanceof PhpDocTagNode) {
return null; return null;
} }
@ -44,9 +44,11 @@ final class ParamTagRemover
if ($docNode->name !== '@param') { if ($docNode->name !== '@param') {
return null; return null;
} }
// skip union types if ($type instanceof Type) {
if ($docNode->value->type instanceof UnionTypeNode) { $paramType = $phpDocInfo->getParamType($docNode->value->parameterName);
return null; if (!$type->equals($paramType)) {
return null;
}
} }
if (!$this->deadParamTagValueNodeAnalyzer->isDead($docNode->value, $functionLike)) { if (!$this->deadParamTagValueNodeAnalyzer->isDead($docNode->value, $functionLike)) {
return null; return null;

View File

@ -93,7 +93,7 @@ CODE_SAMPLE
if (!isset(self::CAST_CLASS_TO_NODE_TYPE[$nodeClass])) { if (!isset(self::CAST_CLASS_TO_NODE_TYPE[$nodeClass])) {
return null; return null;
} }
$nodeType = $this->getType($node->expr); $nodeType = $this->nodeTypeResolver->getNativeType($node->expr);
if ($nodeType instanceof MixedType) { if ($nodeType instanceof MixedType) {
return null; return null;
} }

View File

@ -17,7 +17,7 @@ use Rector\Contract\Rector\ConfigurableRectorInterface;
use Rector\Rector\AbstractRector; use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix202403\Webmozart\Assert\Assert; use RectorPrefix202406\Webmozart\Assert\Assert;
/** /**
* @see \Rector\Tests\DeadCode\Rector\ClassLike\RemoveAnnotationRector\RemoveAnnotationRectorTest * @see \Rector\Tests\DeadCode\Rector\ClassLike\RemoveAnnotationRector\RemoveAnnotationRectorTest
*/ */

View File

@ -6,9 +6,11 @@ namespace Rector\DeadCode\Rector\ClassMethod;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Reflection\ClassReflection;
use Rector\DeadCode\NodeManipulator\ClassMethodParamRemover;
use Rector\NodeAnalyzer\ParamAnalyzer; use Rector\NodeAnalyzer\ParamAnalyzer;
use Rector\Rector\AbstractRector; use Rector\Rector\AbstractRector;
use Rector\Removing\NodeManipulator\ComplexNodeRemover; use Rector\Reflection\ReflectionResolver;
use Rector\ValueObject\MethodName; use Rector\ValueObject\MethodName;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -24,13 +26,19 @@ final class RemoveUnusedConstructorParamRector extends AbstractRector
private $paramAnalyzer; private $paramAnalyzer;
/** /**
* @readonly * @readonly
* @var \Rector\Removing\NodeManipulator\ComplexNodeRemover * @var \Rector\Reflection\ReflectionResolver
*/ */
private $complexNodeRemover; private $reflectionResolver;
public function __construct(ParamAnalyzer $paramAnalyzer, ComplexNodeRemover $complexNodeRemover) /**
* @readonly
* @var \Rector\DeadCode\NodeManipulator\ClassMethodParamRemover
*/
private $classMethodParamRemover;
public function __construct(ParamAnalyzer $paramAnalyzer, ReflectionResolver $reflectionResolver, ClassMethodParamRemover $classMethodParamRemover)
{ {
$this->paramAnalyzer = $paramAnalyzer; $this->paramAnalyzer = $paramAnalyzer;
$this->complexNodeRemover = $complexNodeRemover; $this->reflectionResolver = $reflectionResolver;
$this->classMethodParamRemover = $classMethodParamRemover;
} }
public function getRuleDefinition() : RuleDefinition public function getRuleDefinition() : RuleDefinition
{ {
@ -83,28 +91,20 @@ CODE_SAMPLE
if ($constructorClassMethod->isAbstract()) { if ($constructorClassMethod->isAbstract()) {
return null; return null;
} }
$changedConstructorClassMethod = $this->processRemoveParams($constructorClassMethod); $classReflection = $this->reflectionResolver->resolveClassReflection($node);
if (!$classReflection instanceof ClassReflection) {
return null;
}
$interfaces = $classReflection->getInterfaces();
foreach ($interfaces as $interface) {
if ($interface->hasNativeMethod(MethodName::CONSTRUCT)) {
return null;
}
}
$changedConstructorClassMethod = $this->classMethodParamRemover->processRemoveParams($constructorClassMethod);
if (!$changedConstructorClassMethod instanceof ClassMethod) { if (!$changedConstructorClassMethod instanceof ClassMethod) {
return null; return null;
} }
return $node; return $node;
} }
private function processRemoveParams(ClassMethod $classMethod) : ?ClassMethod
{
$paramKeysToBeRemoved = [];
foreach ($classMethod->params as $key => $param) {
if ($this->paramAnalyzer->isParamUsedInClassMethod($classMethod, $param)) {
continue;
}
$paramKeysToBeRemoved[] = $key;
}
if ($paramKeysToBeRemoved === []) {
return null;
}
$removedParamKeys = $this->complexNodeRemover->processRemoveParamWithKeys($classMethod, $paramKeysToBeRemoved);
if ($removedParamKeys !== []) {
return $classMethod;
}
return null;
}
} }

View File

@ -9,7 +9,12 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\TraitUse; use PhpParser\Node\Stmt\TraitUse;
use PHPStan\Analyser\Scope; use PHPStan\Analyser\Scope;
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\ClassReflection;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover;
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
use Rector\DeadCode\NodeAnalyzer\PropertyWriteonlyAnalyzer; use Rector\DeadCode\NodeAnalyzer\PropertyWriteonlyAnalyzer;
use Rector\PhpParser\Node\BetterNodeFinder; use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\PhpParser\NodeFinder\PropertyFetchFinder; use Rector\PhpParser\NodeFinder\PropertyFetchFinder;
@ -52,13 +57,31 @@ final class RemoveUnusedPromotedPropertyRector extends AbstractScopeAwareRector
* @var \Rector\Reflection\ReflectionResolver * @var \Rector\Reflection\ReflectionResolver
*/ */
private $reflectionResolver; private $reflectionResolver;
public function __construct(PropertyFetchFinder $propertyFetchFinder, VisibilityManipulator $visibilityManipulator, PropertyWriteonlyAnalyzer $propertyWriteonlyAnalyzer, BetterNodeFinder $betterNodeFinder, ReflectionResolver $reflectionResolver) /**
* @readonly
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
*/
private $phpDocInfoFactory;
/**
* @readonly
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover
*/
private $phpDocTagRemover;
/**
* @readonly
* @var \Rector\Comments\NodeDocBlock\DocBlockUpdater
*/
private $docBlockUpdater;
public function __construct(PropertyFetchFinder $propertyFetchFinder, VisibilityManipulator $visibilityManipulator, PropertyWriteonlyAnalyzer $propertyWriteonlyAnalyzer, BetterNodeFinder $betterNodeFinder, ReflectionResolver $reflectionResolver, PhpDocInfoFactory $phpDocInfoFactory, PhpDocTagRemover $phpDocTagRemover, DocBlockUpdater $docBlockUpdater)
{ {
$this->propertyFetchFinder = $propertyFetchFinder; $this->propertyFetchFinder = $propertyFetchFinder;
$this->visibilityManipulator = $visibilityManipulator; $this->visibilityManipulator = $visibilityManipulator;
$this->propertyWriteonlyAnalyzer = $propertyWriteonlyAnalyzer; $this->propertyWriteonlyAnalyzer = $propertyWriteonlyAnalyzer;
$this->betterNodeFinder = $betterNodeFinder; $this->betterNodeFinder = $betterNodeFinder;
$this->reflectionResolver = $reflectionResolver; $this->reflectionResolver = $reflectionResolver;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->phpDocTagRemover = $phpDocTagRemover;
$this->docBlockUpdater = $docBlockUpdater;
} }
public function getRuleDefinition() : RuleDefinition public function getRuleDefinition() : RuleDefinition
{ {
@ -116,6 +139,7 @@ CODE_SAMPLE
return null; return null;
} }
$hasChanged = \false; $hasChanged = \false;
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($constructClassMethod);
foreach ($constructClassMethod->params as $key => $param) { foreach ($constructClassMethod->params as $key => $param) {
// only private local scope; removing public property might be dangerous // only private local scope; removing public property might be dangerous
if (!$this->visibilityManipulator->hasVisibility($param, Visibility::PRIVATE)) { if (!$this->visibilityManipulator->hasVisibility($param, Visibility::PRIVATE)) {
@ -129,15 +153,23 @@ CODE_SAMPLE
if (!$this->propertyWriteonlyAnalyzer->arePropertyFetchesExclusivelyBeingAssignedTo($propertyFetches)) { if (!$this->propertyWriteonlyAnalyzer->arePropertyFetchesExclusivelyBeingAssignedTo($propertyFetches)) {
continue; continue;
} }
// always changed on below code
$hasChanged = \true;
// is variable used? only remove property, keep param // is variable used? only remove property, keep param
$variable = $this->betterNodeFinder->findVariableOfName((array) $constructClassMethod->stmts, $paramName); $variable = $this->betterNodeFinder->findVariableOfName((array) $constructClassMethod->stmts, $paramName);
if ($variable instanceof Variable) { if ($variable instanceof Variable) {
$param->flags = 0; $param->flags = 0;
continue; continue;
} }
if ($phpDocInfo instanceof PhpDocInfo) {
$paramTagValueNode = $phpDocInfo->getParamTagValueByName($paramName);
if ($paramTagValueNode instanceof ParamTagValueNode) {
$this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $paramTagValueNode);
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($constructClassMethod);
}
}
// remove param // remove param
unset($constructClassMethod->params[$key]); unset($constructClassMethod->params[$key]);
$hasChanged = \true;
} }
if ($hasChanged) { if ($hasChanged) {
return $node; return $node;

View File

@ -0,0 +1,105 @@
<?php
declare (strict_types=1);
namespace Rector\DeadCode\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\DeadCode\NodeManipulator\ClassMethodParamRemover;
use Rector\DeadCode\NodeManipulator\VariadicFunctionLikeDetector;
use Rector\NodeAnalyzer\MagicClassMethodAnalyzer;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUnusedPublicMethodParameterRector\RemoveUnusedPublicMethodParameterRectorTest
*/
final class RemoveUnusedPublicMethodParameterRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\DeadCode\NodeManipulator\VariadicFunctionLikeDetector
*/
private $variadicFunctionLikeDetector;
/**
* @readonly
* @var \Rector\DeadCode\NodeManipulator\ClassMethodParamRemover
*/
private $classMethodParamRemover;
/**
* @readonly
* @var \Rector\NodeAnalyzer\MagicClassMethodAnalyzer
*/
private $magicClassMethodAnalyzer;
public function __construct(VariadicFunctionLikeDetector $variadicFunctionLikeDetector, ClassMethodParamRemover $classMethodParamRemover, MagicClassMethodAnalyzer $magicClassMethodAnalyzer)
{
$this->variadicFunctionLikeDetector = $variadicFunctionLikeDetector;
$this->classMethodParamRemover = $classMethodParamRemover;
$this->magicClassMethodAnalyzer = $magicClassMethodAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Remove unused parameter in public method on final class without extends and interface', [new CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
public function run($a, $b)
{
echo $a;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
public function run($a)
{
echo $a;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [Class_::class];
}
/**
* @param Class_ $node
*/
public function refactor(Node $node) : ?Node
{
// may has child, or override parent that needs follow signature
if (!$node->isFinal() || $node->extends instanceof FullyQualified || $node->implements !== []) {
return null;
}
$hasChanged = \false;
foreach ($node->getMethods() as $classMethod) {
if (!$classMethod->isPublic()) {
continue;
}
if ($classMethod->params === []) {
continue;
}
if ($this->magicClassMethodAnalyzer->isUnsafeOverridden($classMethod)) {
continue;
}
if ($this->variadicFunctionLikeDetector->isVariadic($classMethod)) {
continue;
}
$changedMethod = $this->classMethodParamRemover->processRemoveParams($classMethod);
if (!$changedMethod instanceof ClassMethod) {
continue;
}
$hasChanged = \true;
}
if ($hasChanged) {
return $node;
}
return null;
}
}

View File

@ -0,0 +1,87 @@
<?php
declare (strict_types=1);
namespace Rector\DeadCode\Rector\If_;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use PhpParser\Node\Stmt\If_;
use PHPStan\Type\Constant\ConstantBooleanType;
use Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\DeadCode\Rector\If_\ReduceAlwaysFalseIfOrRector\ReduceAlwaysFalseIfOrRectorTest
*/
final class ReduceAlwaysFalseIfOrRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer
*/
private $safeLeftTypeBooleanAndOrAnalyzer;
public function __construct(SafeLeftTypeBooleanAndOrAnalyzer $safeLeftTypeBooleanAndOrAnalyzer)
{
$this->safeLeftTypeBooleanAndOrAnalyzer = $safeLeftTypeBooleanAndOrAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Reduce always false in a if ( || ) condition', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function run(int $number)
{
if (! is_int($number) || $number > 50) {
return 'yes';
}
return 'no';
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function run(int $number)
{
if ($number > 50) {
return 'yes';
}
return 'no';
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [If_::class];
}
/**
* @param If_ $node
*/
public function refactor(Node $node) : ?Node
{
if (!$node->cond instanceof BooleanOr) {
return null;
}
$booleanOr = $node->cond;
$conditionStaticType = $this->getType($booleanOr->left);
if (!$conditionStaticType instanceof ConstantBooleanType) {
return null;
}
if ($conditionStaticType->getValue()) {
return null;
}
if (!$this->safeLeftTypeBooleanAndOrAnalyzer->isSafe($booleanOr)) {
return null;
}
$node->cond = $booleanOr->right;
return $node;
}
}

View File

@ -5,7 +5,9 @@ namespace Rector\DeadCode\Rector\If_;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr; use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch; use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Expr\Variable; use PhpParser\Node\Expr\Variable;
@ -13,12 +15,11 @@ use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Else_; use PhpParser\Node\Stmt\Else_;
use PhpParser\Node\Stmt\If_; use PhpParser\Node\Stmt\If_;
use PhpParser\NodeTraverser; use PhpParser\NodeTraverser;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\Constant\ConstantBooleanType;
use Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer;
use Rector\NodeAnalyzer\ExprAnalyzer; use Rector\NodeAnalyzer\ExprAnalyzer;
use Rector\PhpParser\Node\BetterNodeFinder; use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\Rector\AbstractRector; use Rector\Rector\AbstractRector;
use Rector\Reflection\ReflectionResolver;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/** /**
@ -26,11 +27,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/ */
final class RemoveAlwaysTrueIfConditionRector extends AbstractRector final class RemoveAlwaysTrueIfConditionRector extends AbstractRector
{ {
/**
* @readonly
* @var \Rector\Reflection\ReflectionResolver
*/
private $reflectionResolver;
/** /**
* @readonly * @readonly
* @var \Rector\NodeAnalyzer\ExprAnalyzer * @var \Rector\NodeAnalyzer\ExprAnalyzer
@ -41,11 +37,16 @@ final class RemoveAlwaysTrueIfConditionRector extends AbstractRector
* @var \Rector\PhpParser\Node\BetterNodeFinder * @var \Rector\PhpParser\Node\BetterNodeFinder
*/ */
private $betterNodeFinder; private $betterNodeFinder;
public function __construct(ReflectionResolver $reflectionResolver, ExprAnalyzer $exprAnalyzer, BetterNodeFinder $betterNodeFinder) /**
* @readonly
* @var \Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer
*/
private $safeLeftTypeBooleanAndOrAnalyzer;
public function __construct(ExprAnalyzer $exprAnalyzer, BetterNodeFinder $betterNodeFinder, SafeLeftTypeBooleanAndOrAnalyzer $safeLeftTypeBooleanAndOrAnalyzer)
{ {
$this->reflectionResolver = $reflectionResolver;
$this->exprAnalyzer = $exprAnalyzer; $this->exprAnalyzer = $exprAnalyzer;
$this->betterNodeFinder = $betterNodeFinder; $this->betterNodeFinder = $betterNodeFinder;
$this->safeLeftTypeBooleanAndOrAnalyzer = $safeLeftTypeBooleanAndOrAnalyzer;
} }
public function getRuleDefinition() : RuleDefinition public function getRuleDefinition() : RuleDefinition
{ {
@ -84,10 +85,13 @@ CODE_SAMPLE
} }
/** /**
* @param If_ $node * @param If_ $node
* @return int|null|Stmt[] * @return int|null|Stmt[]|If_
*/ */
public function refactor(Node $node) public function refactor(Node $node)
{ {
if ($node->cond instanceof BooleanAnd) {
return $this->refactorIfWithBooleanAnd($node);
}
if ($node->else instanceof Else_) { if ($node->else instanceof Else_) {
return null; return null;
} }
@ -102,7 +106,7 @@ CODE_SAMPLE
if (!$conditionStaticType->getValue()) { if (!$conditionStaticType->getValue()) {
return null; return null;
} }
if ($this->shouldSkipPropertyFetch($node->cond)) { if ($this->shouldSkipExpr($node->cond)) {
return null; return null;
} }
if ($this->shouldSkipFromParam($node->cond)) { if ($this->shouldSkipFromParam($node->cond)) {
@ -128,25 +132,27 @@ CODE_SAMPLE
} }
return \false; return \false;
} }
private function shouldSkipPropertyFetch(Expr $expr) : bool private function shouldSkipExpr(Expr $expr) : bool
{ {
/** @var PropertyFetch[]|StaticPropertyFetch[] $propertyFetches */ return (bool) $this->betterNodeFinder->findInstancesOf($expr, [PropertyFetch::class, StaticPropertyFetch::class, ArrayDimFetch::class]);
$propertyFetches = $this->betterNodeFinder->findInstancesOf($expr, [PropertyFetch::class, StaticPropertyFetch::class]); }
foreach ($propertyFetches as $propertyFetch) { private function refactorIfWithBooleanAnd(If_ $if) : ?If_
$classReflection = $this->reflectionResolver->resolveClassReflectionSourceObject($propertyFetch); {
if (!$classReflection instanceof ClassReflection) { if (!$if->cond instanceof BooleanAnd) {
// cannot get parent Trait_ from Property Fetch return null;
return \true;
}
$propertyName = (string) $this->nodeNameResolver->getName($propertyFetch);
if (!$classReflection->hasNativeProperty($propertyName)) {
continue;
}
$nativeProperty = $classReflection->getNativeProperty($propertyName);
if (!$nativeProperty->hasNativeType()) {
return \true;
}
} }
return \false; $booleanAnd = $if->cond;
$leftType = $this->getType($booleanAnd->left);
if (!$leftType instanceof ConstantBooleanType) {
return null;
}
if (!$leftType->getValue()) {
return null;
}
if (!$this->safeLeftTypeBooleanAndOrAnalyzer->isSafe($booleanAnd)) {
return null;
}
$if->cond = $booleanAnd->right;
return $if;
} }
} }

View File

@ -6,6 +6,7 @@ namespace Rector\DeadCode\Rector\If_;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr; use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\BooleanNot; use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\CallLike; use PhpParser\Node\Expr\CallLike;
use PhpParser\Node\Expr\Instanceof_; use PhpParser\Node\Expr\Instanceof_;
@ -16,9 +17,11 @@ use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_; use PhpParser\Node\Stmt\If_;
use PhpParser\NodeTraverser; use PhpParser\NodeTraverser;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Type\MixedType; use PHPStan\Type\MixedType;
use Rector\NodeManipulator\IfManipulator; use Rector\NodeManipulator\IfManipulator;
use Rector\Rector\AbstractRector; use Rector\Rector\AbstractRector;
use Rector\Reflection\ReflectionResolver;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/** /**
@ -31,9 +34,15 @@ final class RemoveDeadInstanceOfRector extends AbstractRector
* @var \Rector\NodeManipulator\IfManipulator * @var \Rector\NodeManipulator\IfManipulator
*/ */
private $ifManipulator; private $ifManipulator;
public function __construct(IfManipulator $ifManipulator) /**
* @readonly
* @var \Rector\Reflection\ReflectionResolver
*/
private $reflectionResolver;
public function __construct(IfManipulator $ifManipulator, ReflectionResolver $reflectionResolver)
{ {
$this->ifManipulator = $ifManipulator; $this->ifManipulator = $ifManipulator;
$this->reflectionResolver = $reflectionResolver;
} }
public function getRuleDefinition() : RuleDefinition public function getRuleDefinition() : RuleDefinition
{ {
@ -64,7 +73,7 @@ CODE_SAMPLE
} }
/** /**
* @param If_ $node * @param If_ $node
* @return Stmt[]|null|int * @return Stmt[]|null|int|If_
*/ */
public function refactor(Node $node) public function refactor(Node $node)
{ {
@ -74,6 +83,9 @@ CODE_SAMPLE
if ($node->cond instanceof BooleanNot && $node->cond->expr instanceof Instanceof_) { if ($node->cond instanceof BooleanNot && $node->cond->expr instanceof Instanceof_) {
return $this->refactorStmtAndInstanceof($node, $node->cond->expr); return $this->refactorStmtAndInstanceof($node, $node->cond->expr);
} }
if ($node->cond instanceof BooleanAnd) {
return $this->refactorIfWithBooleanAnd($node);
}
if ($node->cond instanceof Instanceof_) { if ($node->cond instanceof Instanceof_) {
return $this->refactorStmtAndInstanceof($node, $node->cond); return $this->refactorStmtAndInstanceof($node, $node->cond);
} }
@ -84,17 +96,7 @@ CODE_SAMPLE
*/ */
private function refactorStmtAndInstanceof(If_ $if, Instanceof_ $instanceof) private function refactorStmtAndInstanceof(If_ $if, Instanceof_ $instanceof)
{ {
if (!$instanceof->class instanceof Name) { if ($this->isInstanceofTheSameType($instanceof) !== \true) {
return null;
}
// handle in another rule
if ($this->isPropertyFetch($instanceof->expr) || $instanceof->expr instanceof CallLike) {
return null;
}
$classType = $this->nodeTypeResolver->getType($instanceof->class);
$exprType = $this->nodeTypeResolver->getType($instanceof->expr);
$isSameStaticTypeOrSubtype = $classType->equals($exprType) || $classType->isSuperTypeOf($exprType)->yes();
if (!$isSameStaticTypeOrSubtype) {
return null; return null;
} }
if ($this->shouldSkipFromNotTypedParam($instanceof)) { if ($this->shouldSkipFromNotTypedParam($instanceof)) {
@ -125,4 +127,40 @@ CODE_SAMPLE
} }
return $expr instanceof StaticPropertyFetch; return $expr instanceof StaticPropertyFetch;
} }
private function isInstanceofTheSameType(Instanceof_ $instanceof) : ?bool
{
if (!$instanceof->class instanceof Name) {
return null;
}
// handled in another rule
if ($this->isPropertyFetch($instanceof->expr) || $instanceof->expr instanceof CallLike) {
return null;
}
$classReflection = $this->reflectionResolver->resolveClassReflection($instanceof);
if ($classReflection instanceof ClassReflection && $classReflection->isTrait()) {
return null;
}
$classType = $this->nodeTypeResolver->getType($instanceof->class);
$exprType = $this->nodeTypeResolver->getNativeType($instanceof->expr);
if ($classType->equals($exprType)) {
return \true;
}
return $classType->isSuperTypeOf($exprType)->yes();
}
private function refactorIfWithBooleanAnd(If_ $if) : ?\PhpParser\Node\Stmt\If_
{
if (!$if->cond instanceof BooleanAnd) {
return null;
}
$booleanAnd = $if->cond;
if (!$booleanAnd->left instanceof Instanceof_) {
return null;
}
$instanceof = $booleanAnd->left;
if ($this->isInstanceofTheSameType($instanceof) !== \true) {
return null;
}
$if->cond = $booleanAnd->right;
return $if;
}
} }

View File

@ -0,0 +1,107 @@
<?php
declare (strict_types=1);
namespace Rector\DeadCode\Rector\Property;
use PhpParser\Node;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\DeadCode\Rector\Property\RemoveUselessReadOnlyTagRector\RemoveUselessReadOnlyTagRectorTest
*/
final class RemoveUselessReadOnlyTagRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\Privatization\NodeManipulator\VisibilityManipulator
*/
private $visibilityManipulator;
/**
* @readonly
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
*/
private $phpDocInfoFactory;
/**
* @readonly
* @var \Rector\Comments\NodeDocBlock\DocBlockUpdater
*/
private $docBlockUpdater;
public function __construct(VisibilityManipulator $visibilityManipulator, PhpDocInfoFactory $phpDocInfoFactory, DocBlockUpdater $docBlockUpdater)
{
$this->visibilityManipulator = $visibilityManipulator;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->docBlockUpdater = $docBlockUpdater;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Remove useless @readonly annotation on native readonly type', [new CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
/**
* @readonly
*/
private readonly string $name;
public function __construct(string $name)
{
$this->name = $name;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
private readonly string $name;
public function __construct(string $name)
{
$this->name = $name;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [Class_::class, Property::class, Param::class];
}
/**
* @param Class_|Property|Param $node
*/
public function refactor(Node $node) : ?Node
{
// for param, only on property promotion
if ($node instanceof Param && $node->flags === 0) {
return null;
}
if (!$this->visibilityManipulator->isReadonly($node)) {
return null;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$readonlyDoc = $phpDocInfo->getByName('readonly');
if (!$readonlyDoc instanceof PhpDocTagNode) {
return null;
}
if (!$readonlyDoc->value instanceof GenericTagValueNode) {
return null;
}
if ($readonlyDoc->value->value !== '') {
return null;
}
$phpDocInfo->removeByName('readonly');
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node);
return $node;
}
}

View File

@ -3,7 +3,7 @@
declare (strict_types=1); declare (strict_types=1);
namespace Rector\DeadCode\SideEffect; namespace Rector\DeadCode\SideEffect;
use RectorPrefix202403\Nette\Utils\Strings; use RectorPrefix202406\Nette\Utils\Strings;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr; use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayDimFetch; use PhpParser\Node\Expr\ArrayDimFetch;

View File

@ -6,6 +6,7 @@ namespace Rector\EarlyReturn\Rector\Return_;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr; use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\Variable; use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt; use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Expression;
@ -98,6 +99,9 @@ CODE_SAMPLE
$initialAssign = null; $initialAssign = null;
$initialAssignPosition = null; $initialAssignPosition = null;
foreach ($node->stmts as $key => $stmt) { foreach ($node->stmts as $key => $stmt) {
if ($stmt instanceof Expression && $stmt->expr instanceof AssignOp) {
return null;
}
if ($stmt instanceof If_) { if ($stmt instanceof If_) {
$ifs[$key] = $stmt; $ifs[$key] = $stmt;
continue; continue;

Some files were not shown because too many files have changed in this diff Show More