Skip to content

Commit 2291546

Browse files
committed
phpstan: added rule to ban new $class
see #6635 for rationale on why we want to get rid of this for now, this rule will prevent this anti-feature from being used in new code
1 parent 09f0ce4 commit 2291546

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

phpstan.neon.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ includes:
1111

1212
rules:
1313
- pocketmine\phpstan\rules\DeprecatedLegacyEnumAccessRule
14+
- pocketmine\phpstan\rules\DisallowDynamicNewRule
1415
- pocketmine\phpstan\rules\DisallowEnumComparisonRule
1516
- pocketmine\phpstan\rules\DisallowForeachByReferenceRule
1617
- pocketmine\phpstan\rules\ExplodeLimitRule

tests/phpstan/configs/actual-problems.neon

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ parameters:
1818
count: 1
1919
path: ../../../src/Server.php
2020

21+
-
22+
message: '#^Dynamic new is not allowed\.$#'
23+
identifier: pocketmine.new.noDynamic
24+
count: 1
25+
path: ../../../src/Server.php
26+
2127
-
2228
message: '#^Method pocketmine\\Server\:\:getCommandAliases\(\) should return array\<string, list\<string\>\> but returns array\<string, array\<mixed\>\>\.$#'
2329
identifier: return.type
@@ -54,6 +60,12 @@ parameters:
5460
count: 1
5561
path: ../../../src/VersionInfo.php
5662

63+
-
64+
message: '#^Dynamic new is not allowed\.$#'
65+
identifier: pocketmine.new.noDynamic
66+
count: 1
67+
path: ../../../src/block/Block.php
68+
5769
-
5870
message: '#^Parameter \#1 \$x of method pocketmine\\world\\World\:\:getBlockAt\(\) expects int, float\|int given\.$#'
5971
identifier: argument.type
@@ -510,6 +522,12 @@ parameters:
510522
count: 3
511523
path: ../../../src/block/tile/Spawnable.php
512524

525+
-
526+
message: '#^Dynamic new is not allowed\.$#'
527+
identifier: pocketmine.new.noDynamic
528+
count: 1
529+
path: ../../../src/block/tile/TileFactory.php
530+
513531
-
514532
message: '#^Parameter \#1 \$x of method pocketmine\\world\\World\:\:getPotentialLightAt\(\) expects int, float\|int given\.$#'
515533
identifier: argument.type
@@ -936,6 +954,12 @@ parameters:
936954
count: 4
937955
path: ../../../src/plugin/PluginManager.php
938956

957+
-
958+
message: '#^Dynamic new is not allowed\.$#'
959+
identifier: pocketmine.new.noDynamic
960+
count: 1
961+
path: ../../../src/plugin/PluginManager.php
962+
939963
-
940964
message: '#^Method pocketmine\\resourcepacks\\ZippedResourcePack\:\:getPackSize\(\) should return int but returns int\<0, max\>\|false\.$#'
941965
identifier: return.type
@@ -1248,6 +1272,12 @@ parameters:
12481272
count: 1
12491273
path: ../../../src/world/format/io/region/RegionLoader.php
12501274

1275+
-
1276+
message: '#^Dynamic new is not allowed\.$#'
1277+
identifier: pocketmine.new.noDynamic
1278+
count: 1
1279+
path: ../../../src/world/generator/GeneratorRegisterTask.php
1280+
12511281
-
12521282
message: '#^Method pocketmine\\world\\generator\\biome\\BiomeSelector\:\:pickBiome\(\) should return pocketmine\\world\\biome\\Biome but returns pocketmine\\world\\biome\\Biome\|null\.$#'
12531283
identifier: return.type
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
/*
4+
*
5+
* ____ _ _ __ __ _ __ __ ____
6+
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7+
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8+
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9+
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10+
*
11+
* This program is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Lesser General Public License as published by
13+
* the Free Software Foundation, either version 3 of the License, or
14+
* (at your option) any later version.
15+
*
16+
* @author PocketMine Team
17+
* @link http://www.pocketmine.net/
18+
*
19+
*
20+
*/
21+
22+
declare(strict_types=1);
23+
24+
namespace pocketmine\phpstan\rules;
25+
26+
use PhpParser\Node;
27+
use PhpParser\Node\Expr;
28+
use PhpParser\Node\Expr\New_;
29+
use PHPStan\Analyser\Scope;
30+
use PHPStan\Rules\Rule;
31+
use PHPStan\Rules\RuleErrorBuilder;
32+
33+
/**
34+
* @phpstan-implements Rule<New_>
35+
*/
36+
final class DisallowDynamicNewRule implements Rule{
37+
38+
public function getNodeType() : string{
39+
return New_::class;
40+
}
41+
42+
public function processNode(Node $node, Scope $scope) : array{
43+
/** @var New_ $node */
44+
if($node->class instanceof Expr){
45+
return [
46+
RuleErrorBuilder::message("Dynamic new is not allowed.")
47+
->tip("For factories, use closures instead. Closures can implement custom logic, are statically analyzable, and don't restrict the constructor signature.")
48+
->identifier("pocketmine.new.noDynamic")
49+
->build()
50+
];
51+
}
52+
53+
return [];
54+
}
55+
}

0 commit comments

Comments
 (0)