Skip to content

Commit

Permalink
Allow passing mutable object into immutable class to store reference
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Sep 3, 2020
1 parent a4d6a84 commit 8505ca2
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 74 deletions.
Expand Up @@ -1117,26 +1117,6 @@ public static function trackPropertyImpurity(
) {
$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;
}
}
}
}
Expand Down
84 changes: 30 additions & 54 deletions tests/ImmutableAnnotationTest.php
Expand Up @@ -494,6 +494,36 @@ public function getPlusOther(B $b) : int {
}
}',
],
'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;
}
}',
],
];
}

Expand Down Expand Up @@ -631,37 +661,6 @@ public function someInteger() : int {
}',
'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 {
Expand Down Expand Up @@ -696,29 +695,6 @@ public function increment() : void {
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 {
Expand Down

0 comments on commit 8505ca2

Please sign in to comment.