1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-14 18:36:58 +01:00
psalm/src/Psalm/Internal/Codebase/DataFlowGraph.php

87 lines
2.3 KiB
PHP
Raw Normal View History

<?php
namespace Psalm\Internal\Codebase;
use Psalm\Internal\DataFlow\Path;
use Psalm\Internal\DataFlow\DataFlowNode;
2020-05-22 04:47:58 +02:00
use function substr;
use function strlen;
2020-06-19 00:48:19 +02:00
use function array_reverse;
abstract class DataFlowGraph
{
2020-06-22 08:10:03 +02:00
/** @var array<string, array<string, Path>> */
protected $forward_edges = [];
abstract public function addNode(DataFlowNode $node) : void;
2019-08-14 06:47:57 +02:00
/**
* @param array<string> $added_taints
* @param array<string> $removed_taints
2019-08-14 06:47:57 +02:00
*/
2020-05-22 04:47:58 +02:00
public function addPath(
DataFlowNode $from,
DataFlowNode $to,
2020-06-19 00:48:19 +02:00
string $path_type,
2020-06-26 01:12:30 +02:00
?array $added_taints = null,
?array $removed_taints = null
2019-08-14 06:47:57 +02:00
) : void {
2020-05-22 04:47:58 +02:00
$from_id = $from->id;
$to_id = $to->id;
2019-08-14 06:47:57 +02:00
2020-06-19 00:48:19 +02:00
if ($from_id === $to_id) {
return;
}
2020-06-22 08:10:03 +02:00
$this->forward_edges[$from_id][$to_id] = new Path($path_type, $added_taints, $removed_taints);
}
2020-08-23 19:52:31 +02:00
/**
* @param array<string> $previous_path_types
*
* @psalm-pure
*/
protected static function shouldIgnoreFetch(
2020-06-25 07:32:57 +02:00
string $path_type,
string $expression_type,
array $previous_path_types
) : bool {
$el = strlen($expression_type);
2020-06-25 07:32:57 +02:00
if (substr($path_type, 0, $el + 7) === $expression_type . '-fetch-') {
$fetch_nesting = 0;
$previous_path_types = array_reverse($previous_path_types);
foreach ($previous_path_types as $previous_path_type) {
if ($previous_path_type === $expression_type . '-assignment') {
if ($fetch_nesting === 0) {
return false;
}
$fetch_nesting--;
}
if (substr($previous_path_type, 0, $el + 6) === $expression_type . '-fetch') {
$fetch_nesting++;
}
if (substr($previous_path_type, 0, $el + 12) === $expression_type . '-assignment-') {
if ($fetch_nesting > 0) {
$fetch_nesting--;
continue;
}
if (substr($previous_path_type, $el + 12) === substr($path_type, $el + 7)) {
return false;
}
return true;
}
}
}
return false;
}
}