Skip to content

Commit

Permalink
serialize is not pure for array of object
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet committed Nov 3, 2022
1 parent 85b5436 commit 222df2c
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 6 deletions.
8 changes: 2 additions & 6 deletions src/Psalm/Internal/Codebase/Functions.php
Expand Up @@ -530,12 +530,8 @@ public function isCallMapFunctionPure(
if ($function_id === 'serialize' && isset($args[0]) && $type_provider) {
$serialize_type = $type_provider->getType($args[0]->value);

if ($serialize_type) {
foreach ($serialize_type->getAtomicTypes() as $atomic_serialize_type) {
if ($atomic_serialize_type->isObjectType()) {
return false;
}
}
if ($serialize_type && $serialize_type->containsObjectType()) {
return false;
}
}

Expand Down
36 changes: 36 additions & 0 deletions src/Psalm/Internal/TypeVisitor/ContainsObjectTypeVisitor.php
@@ -0,0 +1,36 @@
<?php

namespace Psalm\Internal\TypeVisitor;

use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\NodeVisitor;
use Psalm\Type\TypeNode;

class ContainsObjectTypeVisitor extends NodeVisitor
{
/**
* @var bool
*/
private $contains_object_type = false;

protected function enterNode(TypeNode $type): ?int
{
if ($this instanceof TObject
|| $this instanceof TNamedObject
|| ($this instanceof TTemplateParam
&& $this->as->hasObjectType())
) {
$this->contains_object_type = true;
return NodeVisitor::STOP_TRAVERSAL;
}

return null;
}

public function matches(): bool
{
return $this->contains_object_type;
}
}
10 changes: 10 additions & 0 deletions src/Psalm/Type/Union.php
Expand Up @@ -9,6 +9,7 @@
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Internal\TypeVisitor\ContainsClassLikeVisitor;
use Psalm\Internal\TypeVisitor\ContainsLiteralVisitor;
use Psalm\Internal\TypeVisitor\ContainsObjectTypeVisitor;
use Psalm\Internal\TypeVisitor\FromDocblockSetter;
use Psalm\Internal\TypeVisitor\TemplateTypeCollector;
use Psalm\Internal\TypeVisitor\TypeChecker;
Expand Down Expand Up @@ -1492,6 +1493,15 @@ public function containsAnyLiteral(): bool
return $literal_visitor->matches();
}

public function containsObjectType(): bool
{
$object_type_visitor = new ContainsObjectTypeVisitor();

$object_type_visitor->traverseArray($this->types);

return $object_type_visitor->matches();
}

/**
* @return list<TTemplateParam>
*/
Expand Down
1 change: 1 addition & 0 deletions tests/UnusedCodeTest.php
Expand Up @@ -754,6 +754,7 @@ public function __wakeup(): void
function test(): bool {
try {
serialize(new Foo());
serialize([new Foo()]);
unserialize("");
} catch (\Throwable) {
return false;
Expand Down

0 comments on commit 222df2c

Please sign in to comment.