1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-15 10:57:08 +01:00
psalm/src/Psalm/Internal/Clause.php

175 lines
4.6 KiB
PHP
Raw Normal View History

<?php
2018-11-06 03:57:36 +01:00
namespace Psalm\Internal;
use function array_diff;
2019-07-05 22:24:00 +02:00
use function array_keys;
use function array_map;
use function array_values;
use function count;
use function implode;
use function json_encode;
2019-07-05 22:24:00 +02:00
use function ksort;
use function md5;
2019-07-05 22:24:00 +02:00
use function sort;
use function spl_object_hash;
/**
* @internal
*/
class Clause
{
/** @var ?int */
public $creating_object_id;
/**
* An array of strings of the form
* [
* '$a' => ['falsy'],
* '$b' => ['!falsy'],
* '$c' => ['!null'],
* '$d' => ['string', 'int']
* ]
*
* representing the formula
*
* !$a || $b || $c !== null || is_string($d) || is_int($d)
*
* @var array<string, non-empty-list<string>>
*/
public $possibilities;
/**
* An array of things that are not true
* [
* '$a' => ['!falsy'],
* '$b' => ['falsy'],
* '$c' => ['null'],
* '$d' => ['!string', '!int']
* ]
* represents the formula
*
* $a && !$b && $c === null && !is_string($d) && !is_int($d)
*
* @var array<string, non-empty-list<string>>|null
*/
public $impossibilities;
/** @var bool */
public $wedge;
/** @var bool */
public $reconcilable;
2018-05-07 20:52:45 +02:00
/** @var bool */
public $generated = false;
/** @var array<string, bool> */
public $redefined_vars = [];
/**
* @param array<string, non-empty-list<string>> $possibilities
* @param bool $wedge
* @param bool $reconcilable
2018-05-07 20:52:45 +02:00
* @param bool $generated
* @param array<string, bool> $redefined_vars
*/
public function __construct(
array $possibilities,
$wedge = false,
$reconcilable = true,
$generated = false,
array $redefined_vars = [],
?int $creating_object_id = null
) {
$this->possibilities = $possibilities;
$this->wedge = $wedge;
$this->reconcilable = $reconcilable;
2018-05-07 20:52:45 +02:00
$this->generated = $generated;
$this->redefined_vars = $redefined_vars;
$this->creating_object_id = $creating_object_id;
}
/**
* @param Clause $other_clause
2017-05-27 02:16:18 +02:00
*
* @return bool
*/
public function contains(Clause $other_clause)
{
if (count($other_clause->possibilities) > count($this->possibilities)) {
return false;
}
foreach ($other_clause->possibilities as $var => $possible_types) {
if (!isset($this->possibilities[$var]) || count(array_diff($possible_types, $this->possibilities[$var]))) {
return false;
}
}
return true;
}
/**
* Gets a hash of the object will be unique if we're unable to easily reconcile this with others
*
* @return string
*/
public function getHash()
{
ksort($this->possibilities);
2017-02-02 06:45:23 +01:00
foreach ($this->possibilities as &$possible_types) {
sort($possible_types);
}
$possibility_string = json_encode($this->possibilities);
if (!$possibility_string) {
2019-07-05 22:24:00 +02:00
return (string) \mt_rand(0, 10000000);
}
return md5($possibility_string) .
($this->wedge || !$this->reconcilable ? spl_object_hash($this) : '');
}
2018-05-07 07:26:06 +02:00
public function __toString()
{
return implode(
' || ',
array_map(
/**
* @param string $var_id
* @param string[] $values
*
* @return string
*/
function ($var_id, $values) {
return implode(
2018-05-07 20:52:45 +02:00
' || ',
2018-05-07 07:26:06 +02:00
array_map(
/**
* @param string $value
*
* @return string
*/
function ($value) use ($var_id) {
if ($value === 'falsy') {
return '!' . $var_id;
}
if ($value === '!falsy') {
return $var_id;
}
return $var_id . '==' . $value;
},
$values
)
);
},
array_keys($this->possibilities),
array_values($this->possibilities)
)
);
}
}