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

A little light refactoring

This commit is contained in:
Matthew Brown 2022-03-02 17:27:58 -05:00
parent cb158726a0
commit 54edbdabf6
5 changed files with 46 additions and 47 deletions

View File

@ -216,7 +216,6 @@ class ArrayAssignmentAnalyzer
$current_type,
$root_type,
$offset_already_existed,
$child_stmt,
$parent_var_id
);
} else {
@ -471,7 +470,6 @@ class ArrayAssignmentAnalyzer
Union $value_type,
Union $root_type,
bool $offset_already_existed,
?PhpParser\Node\Expr $child_stmt,
?string $parent_var_id
): Union {
$templated_assignment = false;
@ -525,7 +523,6 @@ class ArrayAssignmentAnalyzer
}
if ($offset_already_existed
&& $child_stmt
&& $parent_var_id
&& ($parent_type = $context->vars_in_scope[$parent_var_id] ?? null)
) {
@ -669,7 +666,8 @@ class ArrayAssignmentAnalyzer
}
/**
* @param array<PhpParser\Node\Expr\ArrayDimFetch> $child_stmts
* @param non-empty-list<PhpParser\Node\Expr\ArrayDimFetch> $child_stmts
* @param-out PhpParser\Node\Expr $child_stmt
*/
private static function analyzeNestedArrayAssignment(
StatementsAnalyzer $statements_analyzer,
@ -688,17 +686,14 @@ class ArrayAssignmentAnalyzer
): void {
$reversed_child_stmts = [];
$var_id_additions = [];
$full_var_id = true;
$child_stmt = null;
if (!empty($child_stmts)) {
$root_var = reset($child_stmts)->var;
}
$root_var = reset($child_stmts)->var;
// First go from the root element up, and go as far as we can to figure out what
// array types there are
while ($child_stmts) {
do {
$child_stmt = array_shift($child_stmts);
if (count($child_stmts)) {
@ -820,12 +815,12 @@ class ArrayAssignmentAnalyzer
$current_dim = $child_stmt->dim;
$parent_var_id = $extended_var_id;
}
} while ($child_stmts);
if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph
&& $root_var_id !== null
&& isset($context->references_to_external_scope[$root_var_id])
&& isset($root_var) && $root_var instanceof Variable && is_string($root_var->name)
&& $root_var instanceof Variable && is_string($root_var->name)
&& $root_var_id === '$' . $root_var->name
) {
// Array is a reference to an external scope, mark it as used
@ -841,7 +836,6 @@ class ArrayAssignmentAnalyzer
if ($root_var_id
&& $full_var_id
&& $child_stmt
&& ($child_stmt_var_type = $statements_analyzer->node_data->getType($child_stmt->var))
&& !$child_stmt_var_type->hasObjectType()
) {

View File

@ -1101,44 +1101,45 @@ class ArrayFetchAnalyzer
): void {
$has_array_access = true;
if ($in_assignment && $type instanceof TArray) {
$from_empty_array = $type->isEmptyArray();
if ($in_assignment) {
if ($type instanceof TArray) {
$from_empty_array = $type->isEmptyArray();
if (count($key_values) === 1) {
$single_atomic = $key_values[0];
$from_mixed_array = $type->type_params[1]->isMixed();
if (count($key_values) === 1) {
$single_atomic = $key_values[0];
$from_mixed_array = $type->type_params[1]->isMixed();
[$previous_key_type, $previous_value_type] = $type->type_params;
[$previous_key_type, $previous_value_type] = $type->type_params;
// ok, type becomes an TKeyedArray
$array_type->removeType($type_string);
$type = new TKeyedArray([
$single_atomic->value => $from_mixed_array ? Type::getMixed() : Type::getNever()
]);
if ($single_atomic instanceof TLiteralClassString) {
$type->class_strings[$single_atomic->value] = true;
// ok, type becomes an TKeyedArray
$array_type->removeType($type_string);
$type = new TKeyedArray([
$single_atomic->value => $from_mixed_array ? Type::getMixed() : Type::getNever()
]);
if ($single_atomic instanceof TLiteralClassString) {
$type->class_strings[$single_atomic->value] = true;
}
$type->sealed = $from_empty_array;
if (!$from_empty_array) {
$type->previous_value_type = clone $previous_value_type;
$type->previous_key_type = clone $previous_key_type;
}
$array_type->addType($type);
} elseif (!$stmt->dim && $from_empty_array && $replacement_type) {
$array_type->removeType($type_string);
$array_type->addType(new TNonEmptyList($replacement_type));
return;
}
$type->sealed = $from_empty_array;
if (!$from_empty_array) {
$type->previous_value_type = clone $previous_value_type;
$type->previous_key_type = clone $previous_key_type;
}
$array_type->addType($type);
} elseif (!$stmt->dim && $from_empty_array && $replacement_type) {
$array_type->removeType($type_string);
$array_type->addType(new TNonEmptyList($replacement_type));
return;
} elseif ($type instanceof TKeyedArray
&& $type->previous_value_type
&& $type->previous_value_type->isMixed()
&& count($key_values) === 1
) {
$type->properties[$key_values[0]->value] = Type::getMixed();
}
} elseif ($in_assignment
&& $type instanceof TKeyedArray
&& $type->previous_value_type
&& $type->previous_value_type->isMixed()
&& count($key_values) === 1
) {
$type->properties[$key_values[0]->value] = Type::getMixed();
}
$offset_type = self::replaceOffsetTypeWithInts($offset_type);

View File

@ -155,6 +155,8 @@ class ReturnAnalyzer
if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === false) {
$context->inside_return = false;
$context->has_returned = true;
return;
}
@ -213,6 +215,8 @@ class ReturnAnalyzer
}
}
$context->has_returned = true;
if ($source instanceof FunctionLikeAnalyzer
&& !($source->getSource() instanceof TraitAnalyzer)
) {

View File

@ -28,9 +28,11 @@ class ThrowAnalyzer
): bool {
$context->inside_throw = true;
if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === false) {
$context->has_returned = true;
return false;
}
$context->inside_throw = false;
$context->has_returned = true;
if ($context->finally_scope) {
foreach ($context->vars_in_scope as $var_id => $type) {

View File

@ -560,10 +560,8 @@ class StatementsAnalyzer extends SourceAnalyzer
UnsetAnalyzer::analyze($statements_analyzer, $stmt, $context);
} elseif ($stmt instanceof PhpParser\Node\Stmt\Return_) {
ReturnAnalyzer::analyze($statements_analyzer, $stmt, $context);
$context->has_returned = true;
} elseif ($stmt instanceof PhpParser\Node\Stmt\Throw_) {
ThrowAnalyzer::analyze($statements_analyzer, $stmt, $context);
$context->has_returned = true;
} elseif ($stmt instanceof PhpParser\Node\Stmt\Switch_) {
SwitchAnalyzer::analyze($statements_analyzer, $stmt, $context);
} elseif ($stmt instanceof PhpParser\Node\Stmt\Break_) {