1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Use arrays instead of strings for assertions

This commit is contained in:
Matthew Brown 2018-05-12 19:38:43 -04:00
parent 7dd86efa13
commit dbc0e6dfcb
8 changed files with 24 additions and 24 deletions

View File

@ -684,7 +684,7 @@ class FunctionChecker extends FunctionLikeChecker
$changed_var_ids = [];
$reconciled_types = Reconciler::reconcileKeyedTypes(
['$inner_type' => $assertions['$' . $first_param->var->name]],
['$inner_type' => [[$assertions['$' . $first_param->var->name]]]],
['$inner_type' => $inner_type],
$changed_var_ids,
['$inner_type' => true],

View File

@ -904,8 +904,10 @@ class IfChecker
foreach ($all_negated_vars as $var_id) {
if (isset($negated_elseif_types[$var_id])) {
if (isset($if_scope->negated_types[$var_id])) {
$if_scope->negated_types[$var_id] = $if_scope->negated_types[$var_id] . '&' .
$negated_elseif_types[$var_id];
$if_scope->negated_types[$var_id] = array_merge(
$if_scope->negated_types[$var_id],
$negated_elseif_types[$var_id]
);
} else {
$if_scope->negated_types[$var_id] = $negated_elseif_types[$var_id];
}

View File

@ -268,8 +268,6 @@ class SwitchChecker
$reconcilable_if_types = Algebra::getTruthsFromFormula($case_context->clauses);
$printer = new PhpParser\PrettyPrinter\Standard;
// if the if has an || in the conditional, we cannot easily reason about it
if ($reconcilable_if_types) {
$changed_var_ids = [];

View File

@ -37,7 +37,7 @@ class IfScope
public $updated_vars = [];
/**
* @var array<string, string>
* @var array<string, array<int, array<int, string>>>
*/
public $negated_types = [];

View File

@ -4,7 +4,7 @@ namespace Psalm\Storage;
class Assertion
{
/**
* @var string the rule being asserted
* @var array<int, array<int, string>> the rule being asserted
*/
public $rule;
@ -16,7 +16,7 @@ class Assertion
/**
* @param string|int $var_id
* @param string $rule
* @param array<int, array<int, string>> $rule
*/
public function __construct($var_id, $rule)
{

View File

@ -282,7 +282,7 @@ class Algebra
* @param array<int, Clause> $clauses
* @param array<string, bool> $cond_referenced_var_ids
*
* @return array<string, string>
* @return array<string, array<int, array<int, string>>>
*/
public static function getTruthsFromFormula(
array $clauses,
@ -303,9 +303,9 @@ class Algebra
// if there's only one possible type, return it
if (count($clause->possibilities) === 1 && count($possible_types) === 1) {
if (isset($truths[$var])) {
$truths[$var] .= '&' . array_pop($possible_types);
$truths[$var][] = [array_pop($possible_types)];
} else {
$truths[$var] = array_pop($possible_types);
$truths[$var] = [[array_pop($possible_types)]];
}
} elseif (count($clause->possibilities) === 1) {
$with_brackets = 0;
@ -360,7 +360,8 @@ class Algebra
unset($cond_referenced_var_ids[$var]);
}
$truths[$var] = implode('|', $things_that_can_be_said);
/** @var array<int, string> $things_that_can_be_said */
$truths[$var] = [$things_that_can_be_said];
}
}
}

View File

@ -41,7 +41,7 @@ class Reconciler
/**
* Takes two arrays and consolidates them, removing null values from existing types where applicable
*
* @param array<string, string> $new_types
* @param array<string, string[][]> $new_types
* @param array<string, Type\Union> $existing_types
* @param array<string> $changed_var_ids
* @param array<string, bool> $referenced_var_ids
@ -61,16 +61,17 @@ class Reconciler
array $suppressed_issues = []
) {
foreach ($new_types as $nk => $type) {
if (strpos($nk, '[') && ($type === '^isset' || $type === '!^empty')) {
if (strpos($nk, '[') && ($type[0][0] === '^isset' || $type[0][0] === '!^empty')) {
$path_parts = self::breakUpPathIntoParts($nk);
if (count($path_parts) > 1) {
$base_key = array_shift($path_parts);
if (!isset($new_types[$base_key])) {
$new_types[$base_key] = '!^bool&!^int';
$new_types[$base_key] = [['!^bool'],['!^int']];
} else {
$new_types[$base_key] .= '&!^bool&!^int';
$new_types[$base_key][] = ['!^bool'];
$new_types[$base_key][] = ['!^int'];
}
}
}
@ -82,9 +83,7 @@ class Reconciler
$project_checker = $statements_checker->getFileChecker()->project_checker;
foreach ($new_types as $key => $new_type_string) {
$new_type_parts = preg_split('/(?<!\')&/', $new_type_string);
foreach ($new_types as $key => $new_type_parts) {
$result_type = isset($existing_types[$key])
? clone $existing_types[$key]
: self::getValueForKey($project_checker, $key, $existing_types);
@ -100,9 +99,7 @@ class Reconciler
$possibly_undefined = $result_type && $result_type->possibly_undefined;
$from_calculation = $result_type && $result_type->from_calculation;
foreach ($new_type_parts as $new_type_part) {
$new_type_part_parts = preg_split('/(?<!\')\|/', $new_type_part);
foreach ($new_type_parts as $new_type_part_parts) {
$orred_type = null;
foreach ($new_type_part_parts as $new_type_part_part) {

View File

@ -801,8 +801,10 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
$rules = \Psalm\Type\Algebra::getTruthsFromFormula($negated_formula);
foreach ($rules as $var_id => $rule) {
if (strpos($rule, '|') !== false) {
continue;
foreach ($rule as $rule_part) {
if (count($rule_part) > 1) {
continue 2;
}
}
if (isset($existing_params[$var_id])) {