mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Check deprecated properties on $this->prop reads
Fixes vimeo/psalm#6118
This commit is contained in:
parent
f015c30a43
commit
af5cdb4dd4
@ -344,6 +344,9 @@ class AtomicPropertyFetchAnalyzer
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: the following line look superfluous, but removing it makes
|
||||
// Psalm\Tests\PropertyTypeTest::testValidCode with data set "callInParentContext"
|
||||
// fail
|
||||
$declaring_property_class = $codebase->properties->getDeclaringClassForProperty(
|
||||
$property_id,
|
||||
true,
|
||||
@ -380,20 +383,9 @@ class AtomicPropertyFetchAnalyzer
|
||||
);
|
||||
|
||||
if (isset($declaring_class_storage->properties[$prop_name])) {
|
||||
$property_storage = $declaring_class_storage->properties[$prop_name];
|
||||
self::checkPropertyDeprecation($prop_name, $declaring_property_class, $stmt, $statements_analyzer);
|
||||
|
||||
if ($property_storage->deprecated) {
|
||||
if (IssueBuffer::accepts(
|
||||
new DeprecatedProperty(
|
||||
$property_id . ' is marked deprecated',
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt),
|
||||
$property_id
|
||||
),
|
||||
$statements_analyzer->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
$property_storage = $declaring_class_storage->properties[$prop_name];
|
||||
|
||||
if ($context->self && !NamespaceAnalyzer::isWithin($context->self, $property_storage->internal)) {
|
||||
if (IssueBuffer::accepts(
|
||||
@ -481,6 +473,36 @@ class AtomicPropertyFetchAnalyzer
|
||||
}
|
||||
}
|
||||
|
||||
public static function checkPropertyDeprecation(
|
||||
string $prop_name,
|
||||
string $declaring_property_class,
|
||||
PhpParser\Node\Expr\PropertyFetch $stmt,
|
||||
StatementsAnalyzer $statements_analyzer
|
||||
): void {
|
||||
$property_id = $declaring_property_class . '::$' . $prop_name;
|
||||
$codebase = $statements_analyzer->getCodebase();
|
||||
$declaring_class_storage = $codebase->classlike_storage_provider->get(
|
||||
$declaring_property_class
|
||||
);
|
||||
|
||||
if (isset($declaring_class_storage->properties[$prop_name])) {
|
||||
$property_storage = $declaring_class_storage->properties[$prop_name];
|
||||
|
||||
if ($property_storage->deprecated) {
|
||||
if (IssueBuffer::accepts(
|
||||
new DeprecatedProperty(
|
||||
$property_id . ' is marked deprecated',
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt),
|
||||
$property_id
|
||||
),
|
||||
$statements_analyzer->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function propertyFetchCanBeAnalyzed(
|
||||
StatementsAnalyzer $statements_analyzer,
|
||||
\Psalm\Codebase $codebase,
|
||||
|
@ -391,6 +391,7 @@ class InstancePropertyFetchAnalyzer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (($stmt_var_type = $statements_analyzer->node_data->getType($stmt->var))
|
||||
&& $stmt_var_type->hasObjectType()
|
||||
&& $stmt->name instanceof PhpParser\Node\Identifier
|
||||
@ -404,6 +405,7 @@ class InstancePropertyFetchAnalyzer
|
||||
|
||||
$property_id = $lhs_type_part->value . '::$' . $stmt->name->name;
|
||||
|
||||
|
||||
$class_storage = $codebase->classlike_storage_provider->get($lhs_type_part->value);
|
||||
|
||||
AtomicPropertyFetchAnalyzer::processTaints(
|
||||
@ -415,6 +417,21 @@ class InstancePropertyFetchAnalyzer
|
||||
$in_assignment
|
||||
);
|
||||
|
||||
$declaring_property_class = $codebase->properties->getDeclaringClassForProperty(
|
||||
$property_id,
|
||||
true,
|
||||
$statements_analyzer
|
||||
);
|
||||
|
||||
if ($declaring_property_class) {
|
||||
AtomicPropertyFetchAnalyzer::checkPropertyDeprecation(
|
||||
$stmt->name->name,
|
||||
$declaring_property_class,
|
||||
$stmt,
|
||||
$statements_analyzer
|
||||
);
|
||||
}
|
||||
|
||||
$codebase->properties->propertyExists(
|
||||
$property_id,
|
||||
true,
|
||||
|
@ -168,6 +168,38 @@ class DeprecatedAnnotationTest extends TestCase
|
||||
$a->foo = 5;',
|
||||
'error_message' => 'DeprecatedProperty',
|
||||
],
|
||||
'deprecatedPropertyGetFromInsideTheClass' => [
|
||||
'<?php
|
||||
class A{
|
||||
/**
|
||||
* @deprecated
|
||||
* @var ?int
|
||||
*/
|
||||
public $foo;
|
||||
public function bar(): void
|
||||
{
|
||||
echo $this->foo;
|
||||
}
|
||||
}
|
||||
',
|
||||
'error_message' => 'DeprecatedProperty',
|
||||
],
|
||||
'deprecatedPropertySetFromInsideTheClass' => [
|
||||
'<?php
|
||||
class A{
|
||||
/**
|
||||
* @deprecated
|
||||
* @var ?int
|
||||
*/
|
||||
public $foo;
|
||||
public function bar(int $p): void
|
||||
{
|
||||
$this->foo = $p;
|
||||
}
|
||||
}
|
||||
',
|
||||
'error_message' => 'DeprecatedProperty',
|
||||
],
|
||||
'deprecatedClassConstant' => [
|
||||
'<?php
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user