2017-02-18 19:41:27 +01:00
|
|
|
|
<?php
|
|
|
|
|
namespace Psalm\Provider;
|
|
|
|
|
|
|
|
|
|
use Psalm\Checker\ClassLikeChecker;
|
2017-07-29 21:05:06 +02:00
|
|
|
|
use Psalm\Checker\ProjectChecker;
|
2018-10-07 02:11:19 +02:00
|
|
|
|
use Psalm\Codebase;
|
2017-05-19 06:48:26 +02:00
|
|
|
|
use Psalm\Config;
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
2018-09-26 22:33:59 +02:00
|
|
|
|
/**
|
|
|
|
|
* @psalm-type IssueData = array{
|
|
|
|
|
* severity: string,
|
|
|
|
|
* line_from: int,
|
|
|
|
|
* line_to: int,
|
|
|
|
|
* type: string,
|
|
|
|
|
* message: string,
|
|
|
|
|
* file_name: string,
|
|
|
|
|
* file_path: string,
|
|
|
|
|
* snippet: string,
|
|
|
|
|
* from: int,
|
|
|
|
|
* to: int,
|
|
|
|
|
* snippet_from: int,
|
|
|
|
|
* snippet_to: int,
|
|
|
|
|
* column_from: int,
|
|
|
|
|
* column_to: int
|
|
|
|
|
* }
|
2018-10-07 02:11:19 +02:00
|
|
|
|
*
|
|
|
|
|
* @psalm-type TaggedCodeType = array<int, array{0: int, 1: string}>
|
2018-09-26 22:33:59 +02:00
|
|
|
|
*/
|
2017-02-18 23:49:34 +01:00
|
|
|
|
/**
|
|
|
|
|
* Used to determine which files reference other files, necessary for using the --diff
|
|
|
|
|
* option from the command line.
|
|
|
|
|
*/
|
2017-02-18 19:41:27 +01:00
|
|
|
|
class FileReferenceProvider
|
|
|
|
|
{
|
2018-09-30 05:51:06 +02:00
|
|
|
|
/**
|
|
|
|
|
* @var bool
|
|
|
|
|
*/
|
|
|
|
|
private $loaded_from_cache = false;
|
|
|
|
|
|
2017-02-18 19:41:27 +01:00
|
|
|
|
/**
|
|
|
|
|
* A lookup table used for getting all the files that reference a class
|
|
|
|
|
*
|
|
|
|
|
* @var array<string, array<string,bool>>
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
private static $file_references_to_class = [];
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A lookup table used for getting all the files that reference any other file
|
|
|
|
|
*
|
|
|
|
|
* @var array<string,array<string,bool>>
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
private static $referencing_files = [];
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var array<string, array<int,string>>
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
private static $files_inheriting_classes = [];
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A list of all files deleted since the last successful run
|
|
|
|
|
*
|
|
|
|
|
* @var array<int, string>|null
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
private static $deleted_files = null;
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A lookup table used for getting all the files referenced by a file
|
|
|
|
|
*
|
|
|
|
|
* @var array<string, array{a:array<int, string>, i:array<int, string>}>
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
private static $file_references = [];
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
2018-09-26 00:37:24 +02:00
|
|
|
|
/**
|
|
|
|
|
* @var array<string, array<string, bool>>
|
|
|
|
|
*/
|
|
|
|
|
private static $class_method_references = [];
|
|
|
|
|
|
2018-09-30 05:51:06 +02:00
|
|
|
|
/**
|
2018-10-07 04:58:21 +02:00
|
|
|
|
* @var array<string, array<string, int>>
|
2018-09-30 05:51:06 +02:00
|
|
|
|
*/
|
2018-11-02 02:52:39 +01:00
|
|
|
|
private static $analyzed_methods = [];
|
2018-09-30 05:51:06 +02:00
|
|
|
|
|
2018-09-26 22:33:59 +02:00
|
|
|
|
/**
|
|
|
|
|
* @var array<string, array<int, IssueData>>
|
|
|
|
|
*/
|
|
|
|
|
private static $issues = [];
|
|
|
|
|
|
2018-10-26 22:17:15 +02:00
|
|
|
|
/**
|
|
|
|
|
* @var array<string, array{0: array<int, array{0: int, 1: string}>, 1: array<int, array{0: int, 1: string}>}>
|
|
|
|
|
*/
|
|
|
|
|
private static $file_maps = [];
|
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
/**
|
|
|
|
|
* @var ?FileReferenceCacheProvider
|
|
|
|
|
*/
|
|
|
|
|
public $cache;
|
|
|
|
|
|
|
|
|
|
public function __construct(FileReferenceCacheProvider $cache = null)
|
|
|
|
|
{
|
|
|
|
|
$this->cache = $cache;
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-18 19:41:27 +01:00
|
|
|
|
/**
|
|
|
|
|
* @return array<string>
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function getDeletedReferencedFiles()
|
2017-02-18 19:41:27 +01:00
|
|
|
|
{
|
|
|
|
|
if (self::$deleted_files === null) {
|
|
|
|
|
self::$deleted_files = array_filter(
|
|
|
|
|
array_keys(self::$file_references),
|
|
|
|
|
/**
|
|
|
|
|
* @param string $file_name
|
2017-05-27 02:16:18 +02:00
|
|
|
|
*
|
2017-02-18 19:41:27 +01:00
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
function ($file_name) {
|
|
|
|
|
return !file_exists($file_name);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return self::$deleted_files;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $source_file
|
2017-07-25 22:11:02 +02:00
|
|
|
|
* @param string $fq_class_name_lc
|
2017-05-27 02:16:18 +02:00
|
|
|
|
*
|
2017-02-18 19:41:27 +01:00
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function addFileReferenceToClass($source_file, $fq_class_name_lc)
|
2017-02-18 19:41:27 +01:00
|
|
|
|
{
|
|
|
|
|
self::$referencing_files[$source_file] = true;
|
2017-07-25 22:11:02 +02:00
|
|
|
|
self::$file_references_to_class[$fq_class_name_lc][$source_file] = true;
|
2017-02-18 19:41:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-08-22 18:38:38 +02:00
|
|
|
|
/**
|
|
|
|
|
* @return array<string, array<string,bool>>
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function getAllFileReferences()
|
2017-08-22 18:38:38 +02:00
|
|
|
|
{
|
|
|
|
|
return self::$file_references_to_class;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param array<string, array<string,bool>> $references
|
2018-05-03 19:56:30 +02:00
|
|
|
|
* @psalm-suppress MixedTypeCoercion
|
2017-08-22 18:38:38 +02:00
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function addFileReferences(array $references)
|
2017-08-22 18:38:38 +02:00
|
|
|
|
{
|
|
|
|
|
self::$file_references_to_class = array_merge_recursive($references, self::$file_references_to_class);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-18 19:41:27 +01:00
|
|
|
|
/**
|
|
|
|
|
* @param string $source_file
|
2017-07-25 22:11:02 +02:00
|
|
|
|
* @param string $fq_class_name_lc
|
2017-05-27 02:16:18 +02:00
|
|
|
|
*
|
2017-02-18 19:41:27 +01:00
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function addFileInheritanceToClass($source_file, $fq_class_name_lc)
|
2017-02-18 19:41:27 +01:00
|
|
|
|
{
|
2017-07-25 22:11:02 +02:00
|
|
|
|
self::$files_inheriting_classes[$fq_class_name_lc][$source_file] = true;
|
2017-02-18 19:41:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $file
|
2017-05-27 02:16:18 +02:00
|
|
|
|
*
|
2017-02-18 19:41:27 +01:00
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2018-10-07 02:11:19 +02:00
|
|
|
|
private function calculateFilesReferencingFile(Codebase $codebase, $file)
|
2017-02-18 19:41:27 +01:00
|
|
|
|
{
|
|
|
|
|
$referenced_files = [];
|
|
|
|
|
|
2018-10-07 02:11:19 +02:00
|
|
|
|
$file_classes = ClassLikeChecker::getClassesForFile($codebase, $file);
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
2018-02-12 04:49:19 +01:00
|
|
|
|
foreach ($file_classes as $file_class_lc => $_) {
|
|
|
|
|
if (isset(self::$file_references_to_class[$file_class_lc])) {
|
2017-02-18 19:41:27 +01:00
|
|
|
|
$referenced_files = array_merge(
|
|
|
|
|
$referenced_files,
|
2018-02-12 04:49:19 +01:00
|
|
|
|
array_keys(self::$file_references_to_class[$file_class_lc])
|
2017-02-18 19:41:27 +01:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return array_unique($referenced_files);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $file
|
2017-05-27 02:16:18 +02:00
|
|
|
|
*
|
2017-02-18 19:41:27 +01:00
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2018-10-07 02:11:19 +02:00
|
|
|
|
private function calculateFilesInheritingFile(Codebase $codebase, $file)
|
2017-02-18 19:41:27 +01:00
|
|
|
|
{
|
|
|
|
|
$referenced_files = [];
|
|
|
|
|
|
2018-10-07 02:11:19 +02:00
|
|
|
|
$file_classes = ClassLikeChecker::getClassesForFile($codebase, $file);
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
2018-02-12 04:49:19 +01:00
|
|
|
|
foreach ($file_classes as $file_class_lc => $_) {
|
|
|
|
|
if (isset(self::$files_inheriting_classes[$file_class_lc])) {
|
2017-02-18 19:41:27 +01:00
|
|
|
|
$referenced_files = array_merge(
|
|
|
|
|
$referenced_files,
|
2018-02-12 04:49:19 +01:00
|
|
|
|
array_keys(self::$files_inheriting_classes[$file_class_lc])
|
2017-02-18 19:41:27 +01:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return array_unique($referenced_files);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function removeDeletedFilesFromReferences()
|
2017-02-18 19:41:27 +01:00
|
|
|
|
{
|
|
|
|
|
$deleted_files = self::getDeletedReferencedFiles();
|
|
|
|
|
|
|
|
|
|
if ($deleted_files) {
|
|
|
|
|
foreach ($deleted_files as $file) {
|
|
|
|
|
unset(self::$file_references[$file]);
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
if ($this->cache) {
|
|
|
|
|
$this->cache->setCachedFileReferences(self::$file_references);
|
|
|
|
|
}
|
2017-02-18 19:41:27 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $file
|
2017-05-27 02:16:18 +02:00
|
|
|
|
*
|
2017-02-18 19:41:27 +01:00
|
|
|
|
* @return array<string>
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function getFilesReferencingFile($file)
|
2017-02-18 19:41:27 +01:00
|
|
|
|
{
|
|
|
|
|
return isset(self::$file_references[$file]['a']) ? self::$file_references[$file]['a'] : [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $file
|
2017-05-27 02:16:18 +02:00
|
|
|
|
*
|
2017-02-18 19:41:27 +01:00
|
|
|
|
* @return array<string>
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function getFilesInheritingFromFile($file)
|
2017-02-18 19:41:27 +01:00
|
|
|
|
{
|
|
|
|
|
return isset(self::$file_references[$file]['i']) ? self::$file_references[$file]['i'] : [];
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-26 00:37:24 +02:00
|
|
|
|
/**
|
2018-09-26 23:54:08 +02:00
|
|
|
|
* @return array<string, array<string, bool>>
|
2018-09-26 00:37:24 +02:00
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function getMethodsReferencing()
|
2018-09-26 00:37:24 +02:00
|
|
|
|
{
|
2018-09-26 23:54:08 +02:00
|
|
|
|
return self::$class_method_references;
|
2018-09-26 00:37:24 +02:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-18 19:41:27 +01:00
|
|
|
|
/**
|
2018-10-17 17:03:32 +02:00
|
|
|
|
* @param bool $force_reload
|
2017-02-18 19:41:27 +01:00
|
|
|
|
* @return bool
|
|
|
|
|
* @psalm-suppress MixedAssignment
|
2018-05-03 19:56:30 +02:00
|
|
|
|
* @psalm-suppress MixedTypeCoercion
|
2017-02-18 19:41:27 +01:00
|
|
|
|
*/
|
2018-10-17 17:03:32 +02:00
|
|
|
|
public function loadReferenceCache($force_reload = true)
|
2017-02-18 19:41:27 +01:00
|
|
|
|
{
|
2018-10-17 17:03:32 +02:00
|
|
|
|
if ($this->cache && (!$this->loaded_from_cache || $force_reload)) {
|
2018-09-30 05:51:06 +02:00
|
|
|
|
$this->loaded_from_cache = true;
|
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
$file_references = $this->cache->getCachedFileReferences();
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
if ($file_references === null) {
|
2018-09-26 00:37:24 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
self::$file_references = $file_references;
|
2017-02-18 19:41:27 +01:00
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
$class_method_references = $this->cache->getCachedMethodReferences();
|
2017-05-25 04:07:49 +02:00
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
if ($class_method_references === null) {
|
2018-09-26 00:37:24 +02:00
|
|
|
|
return false;
|
2017-02-18 19:41:27 +01:00
|
|
|
|
}
|
2018-09-26 00:37:24 +02:00
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
self::$class_method_references = $class_method_references;
|
2018-09-26 00:37:24 +02:00
|
|
|
|
|
2018-11-02 02:52:39 +01:00
|
|
|
|
$analyzed_methods = $this->cache->getAnalyzedMethodCache();
|
2018-10-07 02:11:19 +02:00
|
|
|
|
|
2018-11-02 02:52:39 +01:00
|
|
|
|
if ($analyzed_methods === false) {
|
2018-10-07 02:11:19 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-02 02:52:39 +01:00
|
|
|
|
self::$analyzed_methods = $analyzed_methods;
|
2018-10-07 02:11:19 +02:00
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
$issues = $this->cache->getCachedIssues();
|
2018-09-26 22:33:59 +02:00
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
if ($issues === null) {
|
2018-09-26 22:33:59 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
self::$issues = $issues;
|
2018-09-26 22:33:59 +02:00
|
|
|
|
|
2018-10-26 22:17:15 +02:00
|
|
|
|
self::$file_maps = $this->cache->getFileMapCache() ?: [];
|
|
|
|
|
|
2018-09-26 00:37:24 +02:00
|
|
|
|
return true;
|
2017-02-18 19:41:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2018-09-28 22:18:45 +02:00
|
|
|
|
* @param array<string, string|bool> $visited_files
|
2017-05-27 02:16:18 +02:00
|
|
|
|
*
|
2017-02-18 19:41:27 +01:00
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-10-07 02:11:19 +02:00
|
|
|
|
public function updateReferenceCache(Codebase $codebase, array $visited_files)
|
2017-02-18 19:41:27 +01:00
|
|
|
|
{
|
2018-09-28 22:18:45 +02:00
|
|
|
|
foreach ($visited_files as $file => $_) {
|
|
|
|
|
$all_file_references = array_unique(
|
|
|
|
|
array_merge(
|
|
|
|
|
isset(self::$file_references[$file]['a']) ? self::$file_references[$file]['a'] : [],
|
2018-10-07 02:11:19 +02:00
|
|
|
|
$this->calculateFilesReferencingFile($codebase, $file)
|
2018-09-28 22:18:45 +02:00
|
|
|
|
)
|
|
|
|
|
);
|
2018-09-26 00:37:24 +02:00
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
$inheritance_references = array_unique(
|
|
|
|
|
array_merge(
|
|
|
|
|
isset(self::$file_references[$file]['i']) ? self::$file_references[$file]['i'] : [],
|
2018-10-07 02:11:19 +02:00
|
|
|
|
$this->calculateFilesInheritingFile($codebase, $file)
|
2018-09-28 22:18:45 +02:00
|
|
|
|
)
|
|
|
|
|
);
|
2018-09-26 00:37:24 +02:00
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
self::$file_references[$file] = [
|
|
|
|
|
'a' => $all_file_references,
|
|
|
|
|
'i' => $inheritance_references,
|
|
|
|
|
];
|
2018-09-26 00:37:24 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-09-28 22:18:45 +02:00
|
|
|
|
if ($this->cache) {
|
|
|
|
|
$this->cache->setCachedFileReferences(self::$file_references);
|
|
|
|
|
$this->cache->setCachedMethodReferences(self::$class_method_references);
|
|
|
|
|
$this->cache->setCachedIssues(self::$issues);
|
2018-10-26 22:17:15 +02:00
|
|
|
|
$this->cache->setFileMapCache(self::$file_maps);
|
2018-11-02 02:52:39 +01:00
|
|
|
|
$this->cache->setAnalyzedMethodCache(self::$analyzed_methods);
|
2018-09-26 00:37:24 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2018-09-27 19:32:08 +02:00
|
|
|
|
* @param string $calling_method_id
|
|
|
|
|
* @param string $referenced_member_id
|
2018-09-26 00:37:24 +02:00
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function addReferenceToClassMethod($calling_method_id, $referenced_member_id)
|
2018-09-26 00:37:24 +02:00
|
|
|
|
{
|
|
|
|
|
if (!isset(self::$class_method_references[$referenced_member_id])) {
|
|
|
|
|
self::$class_method_references[$referenced_member_id] = [$calling_method_id => true];
|
|
|
|
|
} else {
|
|
|
|
|
self::$class_method_references[$referenced_member_id][$calling_method_id] = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return array<string, array<string,bool>>
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function getClassMethodReferences() : array
|
2018-09-26 00:37:24 +02:00
|
|
|
|
{
|
|
|
|
|
return self::$class_method_references;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param array<string, array<string,bool>> $references
|
|
|
|
|
* @psalm-suppress MixedTypeCoercion
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function addClassMethodReferences(array $references)
|
2018-09-26 00:37:24 +02:00
|
|
|
|
{
|
|
|
|
|
foreach ($references as $referenced_member_id => $calling_method_ids) {
|
|
|
|
|
if (isset(self::$class_method_references[$referenced_member_id])) {
|
|
|
|
|
self::$class_method_references[$referenced_member_id] = array_merge(
|
|
|
|
|
self::$class_method_references[$referenced_member_id],
|
|
|
|
|
$calling_method_ids
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
self::$class_method_references[$referenced_member_id] = $calling_method_ids;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-26 22:33:59 +02:00
|
|
|
|
/**
|
|
|
|
|
* @return array<string, array<int, IssueData>>
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function getExistingIssues() : array
|
2018-09-26 22:33:59 +02:00
|
|
|
|
{
|
|
|
|
|
return self::$issues;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2018-09-30 05:51:06 +02:00
|
|
|
|
* @param string $file_path
|
2018-09-26 22:33:59 +02:00
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-09-30 05:51:06 +02:00
|
|
|
|
public function clearExistingIssuesForFile($file_path)
|
2018-09-26 22:33:59 +02:00
|
|
|
|
{
|
2018-09-30 05:51:06 +02:00
|
|
|
|
unset(self::$issues[$file_path]);
|
2018-09-26 22:33:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2018-09-27 19:32:08 +02:00
|
|
|
|
* @param string $file_path
|
2018-10-17 21:52:26 +02:00
|
|
|
|
* @param IssueData $issue
|
2018-09-26 22:33:59 +02:00
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-10-26 22:17:15 +02:00
|
|
|
|
public function clearExistingFileMapsForFile($file_path)
|
|
|
|
|
{
|
|
|
|
|
unset(self::$file_maps[$file_path]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $file_path
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-09-28 22:18:45 +02:00
|
|
|
|
public function addIssue($file_path, array $issue)
|
2018-09-26 22:33:59 +02:00
|
|
|
|
{
|
2018-10-17 21:52:26 +02:00
|
|
|
|
// don’t save parse errors ever, as they're not responsive to AST diffing
|
|
|
|
|
if ($issue['type'] === 'ParseError') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-26 22:33:59 +02:00
|
|
|
|
if (!isset(self::$issues[$file_path])) {
|
|
|
|
|
self::$issues[$file_path] = [$issue];
|
|
|
|
|
} else {
|
|
|
|
|
self::$issues[$file_path][] = $issue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-30 05:51:06 +02:00
|
|
|
|
/**
|
2018-11-02 02:52:39 +01:00
|
|
|
|
* @param array<string, array<string, int>> $analyzed_methods
|
2018-10-07 02:11:19 +02:00
|
|
|
|
* @return void
|
2018-09-30 05:51:06 +02:00
|
|
|
|
*/
|
2018-11-02 02:52:39 +01:00
|
|
|
|
public function setAnalyzedMethods(array $analyzed_methods)
|
2018-09-30 05:51:06 +02:00
|
|
|
|
{
|
2018-11-02 02:52:39 +01:00
|
|
|
|
self::$analyzed_methods = $analyzed_methods;
|
2018-09-30 05:51:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-10-26 22:17:15 +02:00
|
|
|
|
/**
|
|
|
|
|
* @param array<string, array{0: TaggedCodeType, 1: TaggedCodeType}> $file_maps
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function setFileMaps(array $file_maps)
|
|
|
|
|
{
|
|
|
|
|
self::$file_maps = $file_maps;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-30 05:51:06 +02:00
|
|
|
|
/**
|
2018-10-07 04:58:21 +02:00
|
|
|
|
* @return array<string, array<string, int>>
|
2018-09-30 05:51:06 +02:00
|
|
|
|
*/
|
2018-11-02 02:52:39 +01:00
|
|
|
|
public function getAnalyzedMethods()
|
2018-09-30 05:51:06 +02:00
|
|
|
|
{
|
2018-11-02 02:52:39 +01:00
|
|
|
|
return self::$analyzed_methods;
|
2018-09-30 05:51:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-10-26 22:17:15 +02:00
|
|
|
|
/**
|
|
|
|
|
* @return array<string, array{0: TaggedCodeType, 1: TaggedCodeType}>
|
|
|
|
|
*/
|
|
|
|
|
public function getFileMaps()
|
|
|
|
|
{
|
|
|
|
|
return self::$file_maps;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-26 00:37:24 +02:00
|
|
|
|
/**
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public static function clearCache()
|
|
|
|
|
{
|
|
|
|
|
self::$file_references_to_class = [];
|
|
|
|
|
self::$referencing_files = [];
|
|
|
|
|
self::$files_inheriting_classes = [];
|
|
|
|
|
self::$deleted_files = null;
|
|
|
|
|
self::$file_references = [];
|
|
|
|
|
self::$class_method_references = [];
|
2018-11-02 02:52:39 +01:00
|
|
|
|
self::$analyzed_methods = [];
|
2018-09-26 22:33:59 +02:00
|
|
|
|
self::$issues = [];
|
2018-10-26 22:17:15 +02:00
|
|
|
|
self::$file_maps = [];
|
2018-09-26 00:37:24 +02:00
|
|
|
|
}
|
2017-02-18 19:41:27 +01:00
|
|
|
|
}
|