mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Group some functionality together
This commit is contained in:
parent
9f9fefe7d6
commit
4b0667bb14
@ -320,117 +320,154 @@ class MethodCallReturnTypeFetcher
|
||||
);
|
||||
|
||||
if ($method_storage->specialize_call
|
||||
&& $var_id
|
||||
&& isset($context->vars_in_scope[$var_id])
|
||||
&& $statements_analyzer->data_flow_graph instanceof TaintFlowGraph
|
||||
) {
|
||||
$var_nodes = [];
|
||||
if ($var_id && isset($context->vars_in_scope[$var_id])) {
|
||||
$var_nodes = [];
|
||||
|
||||
$parent_nodes = $context->vars_in_scope[$var_id]->parent_nodes;
|
||||
$parent_nodes = $context->vars_in_scope[$var_id]->parent_nodes;
|
||||
|
||||
$unspecialized_parent_nodes = array_filter(
|
||||
$parent_nodes,
|
||||
fn($parent_node) => !$parent_node->specialization_key
|
||||
);
|
||||
|
||||
$specialized_parent_nodes = array_filter(
|
||||
$parent_nodes,
|
||||
fn($parent_node) => (bool) $parent_node->specialization_key
|
||||
);
|
||||
|
||||
$var_node = DataFlowNode::getForAssignment(
|
||||
$var_id,
|
||||
new CodeLocation($statements_analyzer, $var_expr)
|
||||
);
|
||||
|
||||
if ($method_storage->location) {
|
||||
$this_parent_node = DataFlowNode::getForAssignment(
|
||||
'$this in ' . $method_id,
|
||||
$method_storage->location
|
||||
$unspecialized_parent_nodes = array_filter(
|
||||
$parent_nodes,
|
||||
fn($parent_node) => !$parent_node->specialization_key
|
||||
);
|
||||
|
||||
foreach ($parent_nodes as $parent_node) {
|
||||
$specialized_parent_nodes = array_filter(
|
||||
$parent_nodes,
|
||||
fn($parent_node) => (bool) $parent_node->specialization_key
|
||||
);
|
||||
|
||||
$var_node = DataFlowNode::getForAssignment(
|
||||
$var_id,
|
||||
new CodeLocation($statements_analyzer, $var_expr)
|
||||
);
|
||||
|
||||
if ($method_storage->location) {
|
||||
$this_parent_node = DataFlowNode::getForAssignment(
|
||||
'$this in ' . $method_id,
|
||||
$method_storage->location
|
||||
);
|
||||
|
||||
foreach ($parent_nodes as $parent_node) {
|
||||
$statements_analyzer->data_flow_graph->addPath(
|
||||
$parent_node,
|
||||
$this_parent_node,
|
||||
'=',
|
||||
$added_taints,
|
||||
$removed_taints
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$var_nodes[$var_node->id] = $var_node;
|
||||
|
||||
$method_call_nodes = [];
|
||||
|
||||
if ($unspecialized_parent_nodes) {
|
||||
$method_call_node = DataFlowNode::getForMethodReturn(
|
||||
(string) $method_id,
|
||||
$cased_method_id,
|
||||
$is_declaring ? ($method_storage->signature_return_type_location
|
||||
?: $method_storage->location) : null,
|
||||
$node_location
|
||||
);
|
||||
|
||||
$method_call_nodes[$method_call_node->id] = $method_call_node;
|
||||
}
|
||||
|
||||
foreach ($specialized_parent_nodes as $parent_node) {
|
||||
$universal_method_call_node = DataFlowNode::getForMethodReturn(
|
||||
(string) $method_id,
|
||||
$cased_method_id,
|
||||
$is_declaring ? ($method_storage->signature_return_type_location
|
||||
?: $method_storage->location) : null,
|
||||
null
|
||||
);
|
||||
|
||||
$method_call_node = new DataFlowNode(
|
||||
strtolower((string) $method_id),
|
||||
$cased_method_id,
|
||||
$is_declaring ? ($method_storage->signature_return_type_location
|
||||
?: $method_storage->location) : null,
|
||||
$parent_node->specialization_key
|
||||
);
|
||||
|
||||
$statements_analyzer->data_flow_graph->addPath(
|
||||
$parent_node,
|
||||
$this_parent_node,
|
||||
$universal_method_call_node,
|
||||
$method_call_node,
|
||||
'=',
|
||||
$added_taints,
|
||||
$removed_taints
|
||||
);
|
||||
|
||||
$method_call_nodes[$method_call_node->id] = $method_call_node;
|
||||
}
|
||||
}
|
||||
|
||||
$var_nodes[$var_node->id] = $var_node;
|
||||
if (!$method_call_nodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
$method_call_nodes = [];
|
||||
foreach ($method_call_nodes as $method_call_node) {
|
||||
$statements_analyzer->data_flow_graph->addNode($method_call_node);
|
||||
|
||||
if ($unspecialized_parent_nodes) {
|
||||
foreach ($var_nodes as $var_node) {
|
||||
$statements_analyzer->data_flow_graph->addNode($var_node);
|
||||
|
||||
$statements_analyzer->data_flow_graph->addPath(
|
||||
$method_call_node,
|
||||
$var_node,
|
||||
'method-call-' . $method_id->method_name,
|
||||
$added_taints,
|
||||
$removed_taints
|
||||
);
|
||||
}
|
||||
|
||||
if (!$is_declaring) {
|
||||
$cased_declaring_method_id = $codebase->methods->getCasedMethodId($declaring_method_id);
|
||||
|
||||
$declaring_method_call_node = new DataFlowNode(
|
||||
strtolower((string) $declaring_method_id),
|
||||
$cased_declaring_method_id,
|
||||
$method_storage->signature_return_type_location ?: $method_storage->location,
|
||||
$method_call_node->specialization_key
|
||||
);
|
||||
|
||||
$statements_analyzer->data_flow_graph->addNode($declaring_method_call_node);
|
||||
$statements_analyzer->data_flow_graph->addPath(
|
||||
$declaring_method_call_node,
|
||||
$method_call_node,
|
||||
'parent',
|
||||
$added_taints,
|
||||
$removed_taints
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$return_type_candidate->parent_nodes = $method_call_nodes;
|
||||
|
||||
$stmt_var_type = clone $context->vars_in_scope[$var_id];
|
||||
|
||||
$stmt_var_type->parent_nodes = $var_nodes;
|
||||
|
||||
$context->vars_in_scope[$var_id] = $stmt_var_type;
|
||||
} else {
|
||||
$method_call_node = DataFlowNode::getForMethodReturn(
|
||||
(string) $method_id,
|
||||
$cased_method_id,
|
||||
$is_declaring ? ($method_storage->signature_return_type_location
|
||||
?: $method_storage->location) : null,
|
||||
$is_declaring
|
||||
? ($method_storage->signature_return_type_location ?: $method_storage->location)
|
||||
: null,
|
||||
$node_location
|
||||
);
|
||||
|
||||
$method_call_nodes[$method_call_node->id] = $method_call_node;
|
||||
}
|
||||
|
||||
foreach ($specialized_parent_nodes as $parent_node) {
|
||||
$universal_method_call_node = DataFlowNode::getForMethodReturn(
|
||||
(string) $method_id,
|
||||
$cased_method_id,
|
||||
$is_declaring ? ($method_storage->signature_return_type_location
|
||||
?: $method_storage->location) : null,
|
||||
null
|
||||
);
|
||||
|
||||
$method_call_node = new DataFlowNode(
|
||||
strtolower((string) $method_id),
|
||||
$cased_method_id,
|
||||
$is_declaring ? ($method_storage->signature_return_type_location
|
||||
?: $method_storage->location) : null,
|
||||
$parent_node->specialization_key
|
||||
);
|
||||
|
||||
$statements_analyzer->data_flow_graph->addPath(
|
||||
$universal_method_call_node,
|
||||
$method_call_node,
|
||||
'=',
|
||||
$added_taints,
|
||||
$removed_taints
|
||||
);
|
||||
|
||||
$method_call_nodes[$method_call_node->id] = $method_call_node;
|
||||
}
|
||||
|
||||
if (!$method_call_nodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($method_call_nodes as $method_call_node) {
|
||||
$statements_analyzer->data_flow_graph->addNode($method_call_node);
|
||||
|
||||
foreach ($var_nodes as $var_node) {
|
||||
$statements_analyzer->data_flow_graph->addNode($var_node);
|
||||
|
||||
$statements_analyzer->data_flow_graph->addPath(
|
||||
$method_call_node,
|
||||
$var_node,
|
||||
'method-call-' . $method_id->method_name,
|
||||
$added_taints,
|
||||
$removed_taints
|
||||
);
|
||||
}
|
||||
|
||||
if (!$is_declaring) {
|
||||
$cased_declaring_method_id = $codebase->methods->getCasedMethodId($declaring_method_id);
|
||||
|
||||
$declaring_method_call_node = new DataFlowNode(
|
||||
strtolower((string) $declaring_method_id),
|
||||
$declaring_method_call_node = DataFlowNode::getForMethodReturn(
|
||||
(string) $declaring_method_id,
|
||||
$cased_declaring_method_id,
|
||||
$method_storage->signature_return_type_location ?: $method_storage->location,
|
||||
$method_call_node->specialization_key
|
||||
$node_location
|
||||
);
|
||||
|
||||
$statements_analyzer->data_flow_graph->addNode($declaring_method_call_node);
|
||||
@ -442,52 +479,13 @@ class MethodCallReturnTypeFetcher
|
||||
$removed_taints
|
||||
);
|
||||
}
|
||||
|
||||
$statements_analyzer->data_flow_graph->addNode($method_call_node);
|
||||
|
||||
$return_type_candidate->parent_nodes = [
|
||||
$method_call_node->id => $method_call_node
|
||||
];
|
||||
}
|
||||
|
||||
$return_type_candidate->parent_nodes = $method_call_nodes;
|
||||
|
||||
$stmt_var_type = clone $context->vars_in_scope[$var_id];
|
||||
|
||||
$stmt_var_type->parent_nodes = $var_nodes;
|
||||
|
||||
$context->vars_in_scope[$var_id] = $stmt_var_type;
|
||||
} elseif ($method_storage->specialize_call
|
||||
&& $statements_analyzer->data_flow_graph instanceof TaintFlowGraph
|
||||
) {
|
||||
$method_call_node = DataFlowNode::getForMethodReturn(
|
||||
(string) $method_id,
|
||||
$cased_method_id,
|
||||
$is_declaring
|
||||
? ($method_storage->signature_return_type_location ?: $method_storage->location)
|
||||
: null,
|
||||
$node_location
|
||||
);
|
||||
|
||||
if (!$is_declaring) {
|
||||
$cased_declaring_method_id = $codebase->methods->getCasedMethodId($declaring_method_id);
|
||||
|
||||
$declaring_method_call_node = DataFlowNode::getForMethodReturn(
|
||||
(string) $declaring_method_id,
|
||||
$cased_declaring_method_id,
|
||||
$method_storage->signature_return_type_location ?: $method_storage->location,
|
||||
$node_location
|
||||
);
|
||||
|
||||
$statements_analyzer->data_flow_graph->addNode($declaring_method_call_node);
|
||||
$statements_analyzer->data_flow_graph->addPath(
|
||||
$declaring_method_call_node,
|
||||
$method_call_node,
|
||||
'parent',
|
||||
$added_taints,
|
||||
$removed_taints
|
||||
);
|
||||
}
|
||||
|
||||
$statements_analyzer->data_flow_graph->addNode($method_call_node);
|
||||
|
||||
$return_type_candidate->parent_nodes = [
|
||||
$method_call_node->id => $method_call_node
|
||||
];
|
||||
} else {
|
||||
$method_call_node = DataFlowNode::getForMethodReturn(
|
||||
(string) $method_id,
|
||||
@ -527,7 +525,11 @@ class MethodCallReturnTypeFetcher
|
||||
];
|
||||
}
|
||||
|
||||
if ($method_storage->taint_source_types && $statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
|
||||
if (!$statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($method_storage->taint_source_types) {
|
||||
$method_node = TaintSource::getForMethodReturn(
|
||||
(string) $method_id,
|
||||
$cased_method_id,
|
||||
@ -539,10 +541,6 @@ class MethodCallReturnTypeFetcher
|
||||
$statements_analyzer->data_flow_graph->addSource($method_node);
|
||||
}
|
||||
|
||||
if (!$statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionCallReturnTypeFetcher::taintUsingFlows(
|
||||
$statements_analyzer,
|
||||
$method_storage,
|
||||
|
Loading…
Reference in New Issue
Block a user