Skip to content

Commit 12af3f1

Browse files
committed
properly set static type in constant array for callable
1 parent e873b34 commit 12af3f1

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
"mglaman\\PHPStanDrupal\\Tests\\": "tests/src/"
4747
},
4848
"classmap": [
49-
"tests/src/Type/data"
49+
"tests/src/Type/data",
50+
"tests/src/Rules/data"
5051
]
5152
},
5253
"extra": {

src/Rules/Drupal/RenderCallbackRule.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ private function doProcessNode(Node\Expr $node, Scope $scope, string $keyChecked
150150
->tip('Change record: https://www.drupal.org/node/2966725.')
151151
->build();
152152
}
153+
154+
if (!$trustedCallbackType->isSuperTypeOf($type)->yes()) {
155+
return RuleErrorBuilder::message(
156+
sprintf("%s callback class %s at key '%s' does not implement Drupal\Core\Security\TrustedCallbackInterface.", $keyChecked, $type->describe(VerbosityLevel::value()), $pos)
157+
)->line($errorLine)->tip('Change record: https://www.drupal.org/node/2966725.')->build();
158+
}
153159
} elseif ($type instanceof ConstantArrayType) {
154160
if (!$type->isCallable()->yes()) {
155161
return RuleErrorBuilder::message(
@@ -204,8 +210,14 @@ private function getType(Node\Expr $node, Scope $scope): Type
204210
if ($node instanceof Node\Expr\BinaryOp\Concat) {
205211
$leftType = $scope->getType($node->left);
206212
$rightType = $scope->getType($node->right);
207-
if ($leftType instanceof GenericClassStringType && $leftType->getGenericType() instanceof StaticType && $rightType instanceof ConstantStringType) {
208-
return new ConstantStringType($leftType->getGenericType()->getClassName() . $rightType->getValue());
213+
if ($rightType instanceof ConstantStringType && $leftType instanceof GenericClassStringType && $leftType->getGenericType() instanceof StaticType) {
214+
return new ConstantArrayType(
215+
[new ConstantIntegerType(0), new ConstantIntegerType(1)],
216+
[
217+
$leftType->getGenericType(),
218+
new ConstantStringType(ltrim($rightType->getValue(), ':'))
219+
]
220+
);
209221
}
210222
}
211223
} elseif ($type instanceof ConstantStringType) {
@@ -234,7 +246,7 @@ private function getType(Node\Expr $node, Scope $scope): Type
234246
return new ConstantArrayType(
235247
[new ConstantIntegerType(0), new ConstantIntegerType(1)],
236248
[
237-
new ConstantStringType($matches[1], true),
249+
new StaticType($this->reflectionProvider->getClass($matches[1])),
238250
new ConstantStringType($matches[2])
239251
]
240252
);

tests/src/Rules/RenderCallbackRuleTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function fileData(): \Generator
5252
'Change record: https://www.drupal.org/node/2966725.',
5353
],
5454
[
55-
"#pre_render callback class 'Drupal\pre_render_callback_rule\NotTrustedCallback' at key '3' does not implement Drupal\Core\Security\TrustedCallbackInterface.",
55+
"#pre_render callback class 'static(Drupal\pre_render_callback_rule\NotTrustedCallback)' at key '3' does not implement Drupal\Core\Security\TrustedCallbackInterface.",
5656
29,
5757
'Change record: https://www.drupal.org/node/2966725.',
5858
],
@@ -100,8 +100,9 @@ public function fileData(): \Generator
100100
__DIR__ . '/data/bug-424.php',
101101
[
102102
[
103-
"#lazy_builder callback 'Bug424\\\Foo:…' at key '0' is not callable.",
103+
"#lazy_builder callback class 'static(Bug424\Foo)' at key '0' does not implement Drupal\Core\Security\TrustedCallbackInterface.",
104104
10,
105+
"Change record: https://www.drupal.org/node/2966725."
105106
],
106107
[
107108
"#lazy_builder callback class 'static(Bug424\Foo)' at key '0' does not implement Drupal\Core\Security\TrustedCallbackInterface.",

0 commit comments

Comments
 (0)