mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 13:51:54 +01:00
Merge pull request #8155 from Nicelocal/prohibition_analyzer_clone
Run method call prohibition analyzer when cloning
This commit is contained in:
commit
8b7bc07ad6
@ -6,6 +6,7 @@ use PhpParser;
|
||||
use Psalm\CodeLocation;
|
||||
use Psalm\Context;
|
||||
use Psalm\Internal\Analyzer\MethodAnalyzer;
|
||||
use Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodCallProhibitionAnalyzer;
|
||||
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
|
||||
use Psalm\Internal\Analyzer\StatementsAnalyzer;
|
||||
use Psalm\Internal\MethodIdentifier;
|
||||
@ -39,6 +40,7 @@ class CloneAnalyzer
|
||||
return false;
|
||||
}
|
||||
|
||||
$location = new CodeLocation($statements_analyzer->getSource(), $stmt);
|
||||
$stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr);
|
||||
|
||||
if ($stmt_expr_type) {
|
||||
@ -71,7 +73,7 @@ class CloneAnalyzer
|
||||
$does_method_exist = $codebase_methods->methodExists(
|
||||
$clone_method_id,
|
||||
$context->calling_method_id,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
$location
|
||||
);
|
||||
$is_method_visible = MethodAnalyzer::isMethodVisible(
|
||||
$clone_method_id,
|
||||
@ -81,6 +83,14 @@ class CloneAnalyzer
|
||||
if ($does_method_exist && !$is_method_visible) {
|
||||
$invalid_clones[] = $clone_type_part->getId();
|
||||
} else {
|
||||
MethodCallProhibitionAnalyzer::analyze(
|
||||
$codebase,
|
||||
$context,
|
||||
$clone_method_id,
|
||||
$statements_analyzer->getNamespace(),
|
||||
$location,
|
||||
$statements_analyzer->getSuppressedIssues()
|
||||
);
|
||||
$possibly_valid = true;
|
||||
$immutable_cloned = true;
|
||||
}
|
||||
@ -108,7 +118,7 @@ class CloneAnalyzer
|
||||
IssueBuffer::maybeAdd(
|
||||
new MixedClone(
|
||||
'Cannot clone mixed',
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
$location
|
||||
),
|
||||
$statements_analyzer->getSuppressedIssues()
|
||||
);
|
||||
@ -119,7 +129,7 @@ class CloneAnalyzer
|
||||
IssueBuffer::maybeAdd(
|
||||
new PossiblyInvalidClone(
|
||||
'Cannot clone ' . $invalid_clones[0],
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
$location
|
||||
),
|
||||
$statements_analyzer->getSuppressedIssues()
|
||||
);
|
||||
@ -127,7 +137,7 @@ class CloneAnalyzer
|
||||
IssueBuffer::maybeAdd(
|
||||
new InvalidClone(
|
||||
'Cannot clone ' . $invalid_clones[0],
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
$location
|
||||
),
|
||||
$statements_analyzer->getSuppressedIssues()
|
||||
);
|
||||
|
@ -26,6 +26,16 @@ class DeprecatedAnnotationTest extends TestCase
|
||||
}
|
||||
}',
|
||||
],
|
||||
'deprecatedCloneMethod' => [
|
||||
'code' => '<?php
|
||||
class Foo {
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function __clone() {
|
||||
}
|
||||
}',
|
||||
],
|
||||
'deprecatedClassUsedInsideClass' => [
|
||||
'code' => '<?php
|
||||
/**
|
||||
@ -114,6 +124,20 @@ class DeprecatedAnnotationTest extends TestCase
|
||||
Foo::barBar();',
|
||||
'error_message' => 'DeprecatedMethod',
|
||||
],
|
||||
'deprecatedCloneMethodWithCall' => [
|
||||
'code' => '<?php
|
||||
class Foo {
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function __clone() {
|
||||
}
|
||||
}
|
||||
|
||||
$a = new Foo;
|
||||
$aa = clone $a;',
|
||||
'error_message' => 'DeprecatedMethod',
|
||||
],
|
||||
'deprecatedClassWithStaticCall' => [
|
||||
'code' => '<?php
|
||||
/**
|
||||
|
@ -586,6 +586,28 @@ class InternalAnnotationTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'The method A\Foo::barBar is internal to A but called from B\Bat',
|
||||
],
|
||||
'internalCloneMethodWithCall' => [
|
||||
'code' => '<?php
|
||||
namespace A {
|
||||
class Foo {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __clone() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace B {
|
||||
class Bat {
|
||||
public function batBat(): void {
|
||||
$a = new \A\Foo;
|
||||
$aa = clone $a;
|
||||
}
|
||||
}
|
||||
}',
|
||||
'error_message' => 'The method A\Foo::__clone is internal to A but called from B\Bat',
|
||||
],
|
||||
'internalMethodWithCallFromRootNamespace' => [
|
||||
'code' => '<?php
|
||||
namespace A {
|
||||
|
Loading…
x
Reference in New Issue
Block a user