diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php index fa4d4a36c46..4d85c3c8413 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php @@ -631,12 +631,13 @@ public function start(PhpParser\Node\FunctionLike $stmt, bool $fake_method = fal $property_storage->location = $param_storage->location; $property_storage->stmt_location = new CodeLocation($this->file_scanner, $param); $property_storage->has_default = (bool)$param->default; + $property_storage->readonly = (bool)($param->flags & PhpParser\Node\Stmt\Class_::MODIFIER_READONLY); $param_storage->promoted_property = true; $property_storage->is_promoted = true; $property_id = $fq_classlike_name . '::$' . $param_storage->name; - switch ($param->flags) { + switch ($param->flags & \PhpParser\Node\Stmt\Class_::VISIBILITY_MODIFIER_MASK) { case \PhpParser\Node\Stmt\Class_::MODIFIER_PUBLIC: $property_storage->visibility = ClassLikeAnalyzer::VISIBILITY_PUBLIC; $classlike_storage->inheritable_property_ids[$param_storage->name] = $property_id; diff --git a/tests/ReadonlyPropertyTest.php b/tests/ReadonlyPropertyTest.php index 7f3a0f131c9..8bec3192352 100644 --- a/tests/ReadonlyPropertyTest.php +++ b/tests/ReadonlyPropertyTest.php @@ -243,6 +243,34 @@ class A { false, '8.1', ], + 'readonlyPromotedPropertyAssignOperator' => [ + 'bar = "goodbye";', + 'error_message' => 'InaccessibleProperty - src' . DIRECTORY_SEPARATOR . 'somefile.php:8:21', + [], + false, + '8.1', + ], + 'readonlyPromotedPropertyAccess' => [ + 'bar;', + 'error_message' => 'InaccessibleProperty - src' . DIRECTORY_SEPARATOR . 'somefile.php:8:26', + [], + false, + '8.1', + ], ]; } }