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:
parent
cb158726a0
commit
54edbdabf6
@ -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()
|
||||
) {
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
) {
|
||||
|
@ -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) {
|
||||
|
@ -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_) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user