Skip to content

Commit 0d8125f

Browse files
committed
Add DrupalRequestStackShimInstantiationRule
1 parent 4462777 commit 0d8125f

File tree

4 files changed

+80
-6
lines changed

4 files changed

+80
-6
lines changed

rules.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ rules:
1818
- mglaman\PHPStanDrupal\Rules\Deprecations\SymfonyCmfRouteObjectInterfaceConstantsRule
1919
- mglaman\PHPStanDrupal\Rules\Deprecations\SymfonyCmfRoutingInClassMethodSignatureRule
2020
- mglaman\PHPStanDrupal\Rules\Drupal\DrupalRequestStackShimInClassMethodRule
21+
- mglaman\PHPStanDrupal\Rules\Drupal\DrupalRequestStackShimInstantiationRule
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace mglaman\PHPStanDrupal\Rules\Drupal;
4+
5+
use mglaman\PHPStanDrupal\Internal\DeprecatedScopeCheck;
6+
use PhpParser\Node;
7+
use PHPStan\Analyser\Scope;
8+
use PHPStan\Rules\Rule;
9+
use PHPStan\Rules\RuleErrorBuilder;
10+
use PHPStan\Type\ObjectType;
11+
12+
final class DrupalRequestStackShimInstantiationRule implements Rule
13+
{
14+
15+
public function getNodeType(): string
16+
{
17+
return Node\Expr\New_::class;
18+
}
19+
20+
public function processNode(Node $node, Scope $scope): array
21+
{
22+
assert($node instanceof Node\Expr\New_);
23+
if (DeprecatedScopeCheck::inDeprecatedScope($scope)) {
24+
return [];
25+
}
26+
[$major, $minor] = explode('.', \Drupal::VERSION, 3);
27+
// Only valid for 9.3 -> 9.5. Deprecated in Drupal 10.
28+
if ($major !== '9' || (int) $minor < 3) {
29+
return [];
30+
}
31+
32+
$symfonyRequestStackType = new ObjectType(\Symfony\Component\HttpFoundation\RequestStack::class);
33+
if ($scope->getType($node)->equals($symfonyRequestStackType)) {
34+
return [
35+
RuleErrorBuilder::message('Do not instantiate Symfony\Component\HttpFoundation\RequestStack. Use \Drupal\Core\Http\RequestStack instead for forward compatibility to Symfony 5.')
36+
->tip('Change record: https://www.drupal.org/node/3253744')
37+
->build(),
38+
];
39+
}
40+
return [];
41+
}
42+
}

tests/src/Rules/DrupalRequestStackShimInClassMethodRuleTest.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ public function testRule(): void
3434
9,
3535
'Change record: https://www.drupal.org/node/3253744',
3636
],
37-
// @todo needs specific \PhpParser\Node\Expr\New_ rule.
38-
[
39-
'',
40-
11,
41-
'Change record: https://www.drupal.org/node/3253744',
42-
],
4337
]
4438
);
4539
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace mglaman\PHPStanDrupal\Tests\Rules;
4+
5+
use mglaman\PHPStanDrupal\Rules\Drupal\DrupalRequestStackShimInstantiationRule;
6+
use mglaman\PHPStanDrupal\Tests\DrupalRuleTestCase;
7+
8+
final class DrupalRequestStackShimInstantiationRuleTest extends DrupalRuleTestCase
9+
{
10+
11+
protected function getRule(): \PHPStan\Rules\Rule
12+
{
13+
return new DrupalRequestStackShimInstantiationRule();
14+
}
15+
16+
public function testRule(): void
17+
{
18+
[$version] = explode('.', \Drupal::VERSION, 2);
19+
if ($version === '8') {
20+
$this->analyse([__DIR__.'/data/request-stack.php'], []);
21+
} elseif ($version === '10') {
22+
self::markTestSkipped('Not tested on 10.x.x');
23+
} else {
24+
$this->analyse(
25+
[__DIR__.'/data/request-stack.php'],
26+
[
27+
[
28+
'Do not instantiate Symfony\Component\HttpFoundation\RequestStack. Use \Drupal\Core\Http\RequestStack instead for forward compatibility to Symfony 5.',
29+
11,
30+
'Change record: https://www.drupal.org/node/3253744',
31+
],
32+
]
33+
);
34+
}
35+
}
36+
37+
}

0 commit comments

Comments
 (0)