1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Allow passing mutable object into immutable class to store reference

This commit is contained in:
Brown 2020-09-03 15:28:09 -04:00
parent a4d6a845f8
commit 8505ca2a23
2 changed files with 30 additions and 74 deletions

View File

@ -1117,26 +1117,6 @@ class InstancePropertyAssignmentAnalyzer
) {
$codebase->analyzer->addMutableClass($declaring_class_storage->name);
}
} elseif ($assignment_value_type
&& ($declaring_class_storage->mutation_free
|| $codebase->alter_code)
) {
$visitor = new \Psalm\Internal\TypeVisitor\ImmutablePropertyAssignmentVisitor(
$statements_analyzer,
$stmt
);
$visitor->traverse($assignment_value_type);
if (!$declaring_class_storage->mutation_free
&& $statements_analyzer->getSource()
instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
&& $statements_analyzer->getSource()->track_mutations
&& $visitor->has_mutation
) {
$statements_analyzer->getSource()->inferred_has_mutation = true;
$statements_analyzer->getSource()->inferred_impure = true;
}
}
}
}

View File

@ -494,6 +494,36 @@ class ImmutableAnnotationTest extends TestCase
}
}',
],
'allowPassingMutableIntoImmutable' => [
'<?php
/**
* @psalm-immutable
*/
class Immutable {
private $item;
public function __construct(Item $item) {
$this->item = $item;
}
public function get(): int {
return $this->item->get();
}
}
class Item {
private int $i = 0;
public function mutate(): void {
$this->i++;
}
/** @psalm-mutation-free */
public function get(): int {
return $this->i;
}
}',
],
];
}
@ -631,37 +661,6 @@ class ImmutableAnnotationTest extends TestCase
}',
'error_message' => 'MissingImmutableAnnotation',
],
'preventPassingMutableIntoImmutable' => [
'<?php
/**
* @psalm-immutable
*/
class Immutable {
private $item;
public function __construct(Item $item) {
$this->item = $item;
}
public function get(): int {
return $this->item->get();
}
}
class Item {
private int $i = 0;
public function mutate(): void {
$this->i++;
}
/** @psalm-mutation-free */
public function get(): int {
return $this->i;
}
}',
'error_message' => 'ImpurePropertyAssignment',
],
'preventNonImmutableTraitInImmutableClass' => [
'<?php
trait MutableTrait {
@ -696,29 +695,6 @@ class ImmutableAnnotationTest extends TestCase
final class NotReallyImmutableClass extends MutableParent {}',
'error_message' => 'MutableDependency'
],
'preventAssigningArrayToImmutableProperty' => [
'<?php
class Item {}
/**
* @psalm-immutable
*/
class Immutable {
/**
* @var Item[]
*/
private $items;
/**
* @param Item[] $items
*/
public function __construct(array $items)
{
$this->items = $items;
}
}',
'error_message' => 'ImpurePropertyAssignment',
],
'mutationInPropertyAssignment' => [
'<?php
class D {