2016-01-07 18:28:27 -05:00
|
|
|
<?php
|
2016-08-13 14:20:46 -04:00
|
|
|
namespace Psalm\Checker;
|
2016-01-07 18:28:27 -05:00
|
|
|
|
2016-11-02 02:29:00 -04:00
|
|
|
use PhpParser;
|
2016-08-13 14:20:46 -04:00
|
|
|
use Psalm\Context;
|
2018-01-05 19:49:27 -05:00
|
|
|
use Psalm\FileManipulation\FileManipulationBuffer;
|
2017-05-19 00:48:26 -04:00
|
|
|
use Psalm\IssueBuffer;
|
2016-11-02 02:29:00 -04:00
|
|
|
use Psalm\StatementsSource;
|
2017-01-02 15:31:18 -05:00
|
|
|
use Psalm\Type;
|
2016-08-13 14:20:46 -04:00
|
|
|
|
2016-11-20 21:49:06 -05:00
|
|
|
class FileChecker extends SourceChecker implements StatementsSource
|
2016-01-07 18:28:27 -05:00
|
|
|
{
|
2017-01-07 14:35:07 -05:00
|
|
|
use CanAlias;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $file_name;
|
|
|
|
|
2016-10-14 00:53:43 -04:00
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
2016-12-03 19:11:30 -05:00
|
|
|
protected $file_path;
|
2016-10-14 00:53:43 -04:00
|
|
|
|
2017-01-07 14:35:07 -05:00
|
|
|
/**
|
2018-05-22 23:38:27 -04:00
|
|
|
* @var array<int, string>
|
|
|
|
*/
|
|
|
|
protected $checked_file_paths = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array<int, string>
|
2017-01-07 14:35:07 -05:00
|
|
|
*/
|
2018-05-22 23:38:27 -04:00
|
|
|
protected $checked_file_names = [];
|
2017-01-07 14:35:07 -05:00
|
|
|
|
|
|
|
/**
|
2018-05-22 23:38:27 -04:00
|
|
|
* @var array<string, bool>
|
2017-01-07 14:35:07 -05:00
|
|
|
*/
|
2018-05-22 23:38:27 -04:00
|
|
|
protected $included_file_paths = [];
|
2017-01-07 14:35:07 -05:00
|
|
|
|
|
|
|
/**
|
2017-10-26 18:19:19 -04:00
|
|
|
* @var array<int, string>
|
2017-01-07 14:35:07 -05:00
|
|
|
*/
|
|
|
|
protected $suppressed_issues = [];
|
|
|
|
|
2016-11-12 18:51:48 -05:00
|
|
|
/**
|
|
|
|
* @var array<string, array<string, string>>
|
2016-10-31 15:42:20 -04:00
|
|
|
*/
|
2016-08-13 18:54:49 -04:00
|
|
|
protected $namespace_aliased_classes = [];
|
2016-02-18 15:05:13 -05:00
|
|
|
|
2016-11-12 18:51:48 -05:00
|
|
|
/**
|
|
|
|
* @var array<string, array<string, string>>
|
|
|
|
*/
|
|
|
|
protected $namespace_aliased_classes_flipped = [];
|
|
|
|
|
2017-01-02 15:31:18 -05:00
|
|
|
/**
|
2018-01-14 13:08:24 -05:00
|
|
|
* @var array<string, InterfaceChecker>
|
2017-01-02 15:31:18 -05:00
|
|
|
*/
|
2017-07-25 16:11:02 -04:00
|
|
|
protected $interface_checkers_to_analyze = [];
|
2017-01-02 15:31:18 -05:00
|
|
|
|
|
|
|
/**
|
2018-01-14 13:08:24 -05:00
|
|
|
* @var array<string, ClassChecker>
|
2017-01-02 15:31:18 -05:00
|
|
|
*/
|
2017-02-01 18:11:00 -05:00
|
|
|
protected $class_checkers_to_analyze = [];
|
2017-01-02 15:31:18 -05:00
|
|
|
|
|
|
|
/**
|
2018-01-28 16:52:57 -05:00
|
|
|
* @var null|Context
|
2017-01-02 15:31:18 -05:00
|
|
|
*/
|
2017-01-12 00:54:41 -05:00
|
|
|
public $context;
|
2017-01-02 15:31:18 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var ProjectChecker
|
|
|
|
*/
|
|
|
|
public $project_checker;
|
|
|
|
|
2016-12-30 18:08:07 -05:00
|
|
|
/**
|
2018-02-18 14:55:11 -08:00
|
|
|
* @param ProjectChecker $project_checker
|
2018-01-21 12:44:46 -05:00
|
|
|
* @param string $file_path
|
|
|
|
* @param string $file_name
|
2016-10-14 00:53:43 -04:00
|
|
|
*/
|
2018-01-21 12:44:46 -05:00
|
|
|
public function __construct(ProjectChecker $project_checker, $file_path, $file_name)
|
|
|
|
{
|
2016-12-30 18:08:07 -05:00
|
|
|
$this->file_path = $file_path;
|
2018-01-21 12:44:46 -05:00
|
|
|
$this->file_name = $file_name;
|
2017-01-02 15:31:18 -05:00
|
|
|
$this->project_checker = $project_checker;
|
2017-07-25 16:11:02 -04:00
|
|
|
}
|
2016-12-28 12:59:51 -05:00
|
|
|
|
2017-07-25 16:11:02 -04:00
|
|
|
/**
|
|
|
|
* @param bool $preserve_checkers
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
2017-09-16 12:45:11 -04:00
|
|
|
public function analyze(Context $file_context = null, $preserve_checkers = false)
|
2017-07-25 16:11:02 -04:00
|
|
|
{
|
2018-02-21 13:54:11 -05:00
|
|
|
$codebase = $this->project_checker->codebase;
|
|
|
|
|
|
|
|
$file_storage = $codebase->file_storage_provider->get($this->file_path);
|
|
|
|
|
|
|
|
if (!$file_storage->deep_scan) {
|
|
|
|
throw new \UnexpectedValueException('File ' . $this->file_path . ' has not been properly scanned');
|
|
|
|
}
|
|
|
|
|
2017-07-25 16:11:02 -04:00
|
|
|
if ($file_context) {
|
|
|
|
$this->context = $file_context;
|
|
|
|
}
|
2017-01-31 19:21:33 -05:00
|
|
|
|
2017-07-25 16:11:02 -04:00
|
|
|
if (!$this->context) {
|
|
|
|
$this->context = new Context();
|
2018-01-21 13:38:51 -05:00
|
|
|
$this->context->collect_references = $codebase->collect_references;
|
2017-07-25 16:11:02 -04:00
|
|
|
}
|
2016-11-02 02:29:00 -04:00
|
|
|
|
2017-12-06 00:56:00 -05:00
|
|
|
$this->context->is_global = true;
|
|
|
|
|
2018-01-21 13:38:51 -05:00
|
|
|
$stmts = $codebase->getStatementsForFile($this->file_path);
|
2016-11-02 02:29:00 -04:00
|
|
|
|
2017-07-25 16:11:02 -04:00
|
|
|
$statements_checker = new StatementsChecker($this);
|
2017-01-02 15:31:18 -05:00
|
|
|
|
2017-07-25 16:11:02 -04:00
|
|
|
$leftover_stmts = $this->populateCheckers($stmts);
|
2016-07-24 17:06:54 -04:00
|
|
|
|
2017-01-02 15:31:18 -05:00
|
|
|
// if there are any leftover statements, evaluate them,
|
|
|
|
// in turn causing the classes/interfaces be evaluated
|
|
|
|
if ($leftover_stmts) {
|
2018-01-21 16:24:20 -05:00
|
|
|
$statements_checker->analyze($leftover_stmts, $this->context, null, null, true);
|
2016-12-28 12:59:51 -05:00
|
|
|
}
|
|
|
|
|
2017-01-02 15:31:18 -05:00
|
|
|
// check any leftover interfaces not already evaluated
|
2017-07-25 16:11:02 -04:00
|
|
|
foreach ($this->interface_checkers_to_analyze as $interface_checker) {
|
|
|
|
$interface_checker->analyze();
|
2016-12-28 12:59:51 -05:00
|
|
|
}
|
|
|
|
|
2017-01-02 15:31:18 -05:00
|
|
|
// check any leftover classes not already evaluated
|
2017-02-01 18:11:00 -05:00
|
|
|
foreach ($this->class_checkers_to_analyze as $class_checker) {
|
2017-09-16 12:45:11 -04:00
|
|
|
$class_checker->analyze(null, $this->context);
|
2016-08-05 15:11:20 -04:00
|
|
|
}
|
|
|
|
|
2017-01-11 21:37:53 -05:00
|
|
|
if (!$preserve_checkers) {
|
2017-02-01 18:11:00 -05:00
|
|
|
$this->class_checkers_to_analyze = [];
|
2017-01-11 21:37:53 -05:00
|
|
|
}
|
2016-01-07 18:28:27 -05:00
|
|
|
}
|
|
|
|
|
2017-07-25 16:11:02 -04:00
|
|
|
/**
|
2018-04-17 12:16:25 -04:00
|
|
|
* @param array<int, PhpParser\Node\Stmt> $stmts
|
2017-07-25 16:11:02 -04:00
|
|
|
*
|
2018-04-17 12:16:25 -04:00
|
|
|
* @return array<int, PhpParser\Node\Stmt>
|
2017-07-25 16:11:02 -04:00
|
|
|
*/
|
|
|
|
public function populateCheckers(array $stmts)
|
|
|
|
{
|
|
|
|
$leftover_stmts = [];
|
|
|
|
|
|
|
|
foreach ($stmts as $stmt) {
|
2017-10-19 19:19:29 -04:00
|
|
|
if ($stmt instanceof PhpParser\Node\Stmt\ClassLike) {
|
|
|
|
$this->populateClassLikeCheckers($stmt);
|
2017-07-25 16:11:02 -04:00
|
|
|
} elseif ($stmt instanceof PhpParser\Node\Stmt\Namespace_) {
|
|
|
|
$namespace_name = $stmt->name ? implode('\\', $stmt->name->parts) : '';
|
|
|
|
|
|
|
|
$namespace_checker = new NamespaceChecker($stmt, $this);
|
|
|
|
$namespace_checker->collectAnalyzableInformation();
|
|
|
|
|
|
|
|
$this->namespace_aliased_classes[$namespace_name] = $namespace_checker->getAliases()->uses;
|
|
|
|
$this->namespace_aliased_classes_flipped[$namespace_name] =
|
|
|
|
$namespace_checker->getAliasedClassesFlipped();
|
|
|
|
} elseif ($stmt instanceof PhpParser\Node\Stmt\Use_) {
|
|
|
|
$this->visitUse($stmt);
|
|
|
|
} elseif ($stmt instanceof PhpParser\Node\Stmt\GroupUse) {
|
|
|
|
$this->visitGroupUse($stmt);
|
2018-02-25 10:43:54 -05:00
|
|
|
} else {
|
2017-10-19 19:19:29 -04:00
|
|
|
if ($stmt instanceof PhpParser\Node\Stmt\If_) {
|
|
|
|
foreach ($stmt->stmts as $if_stmt) {
|
|
|
|
if ($if_stmt instanceof PhpParser\Node\Stmt\ClassLike) {
|
|
|
|
$this->populateClassLikeCheckers($if_stmt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-25 16:11:02 -04:00
|
|
|
$leftover_stmts[] = $stmt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $leftover_stmts;
|
|
|
|
}
|
|
|
|
|
2017-10-19 19:19:29 -04:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
private function populateClassLikeCheckers(PhpParser\Node\Stmt\ClassLike $stmt)
|
|
|
|
{
|
|
|
|
if (!$stmt->name) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($stmt instanceof PhpParser\Node\Stmt\Class_) {
|
2018-04-17 12:16:25 -04:00
|
|
|
$class_checker = new ClassChecker($stmt, $this, $stmt->name->name);
|
2017-10-19 19:19:29 -04:00
|
|
|
|
|
|
|
$fq_class_name = $class_checker->getFQCLN();
|
|
|
|
|
|
|
|
$this->class_checkers_to_analyze[strtolower($fq_class_name)] = $class_checker;
|
|
|
|
} elseif ($stmt instanceof PhpParser\Node\Stmt\Interface_) {
|
2018-04-17 12:16:25 -04:00
|
|
|
$class_checker = new InterfaceChecker($stmt, $this, $stmt->name->name);
|
2017-10-19 19:19:29 -04:00
|
|
|
|
|
|
|
$fq_class_name = $class_checker->getFQCLN();
|
|
|
|
|
|
|
|
$this->interface_checkers_to_analyze[$fq_class_name] = $class_checker;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-01 18:11:00 -05:00
|
|
|
/**
|
|
|
|
* @param string $fq_class_name
|
|
|
|
* @param ClassChecker $class_checker
|
2017-05-26 20:16:18 -04:00
|
|
|
*
|
2017-02-01 18:11:00 -05:00
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function addNamespacedClassChecker($fq_class_name, ClassChecker $class_checker)
|
|
|
|
{
|
2017-07-25 16:11:02 -04:00
|
|
|
$this->class_checkers_to_analyze[strtolower($fq_class_name)] = $class_checker;
|
2017-02-01 18:11:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $fq_class_name
|
|
|
|
* @param InterfaceChecker $interface_checker
|
2017-05-26 20:16:18 -04:00
|
|
|
*
|
2017-02-01 18:11:00 -05:00
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function addNamespacedInterfaceChecker($fq_class_name, InterfaceChecker $interface_checker)
|
|
|
|
{
|
2017-07-25 16:11:02 -04:00
|
|
|
$this->interface_checkers_to_analyze[strtolower($fq_class_name)] = $interface_checker;
|
2017-02-01 18:11:00 -05:00
|
|
|
}
|
|
|
|
|
2017-01-11 21:37:53 -05:00
|
|
|
/**
|
2017-01-12 00:54:41 -05:00
|
|
|
* @param string $method_id
|
2017-01-11 21:37:53 -05:00
|
|
|
* @param Context $this_context
|
2017-05-26 20:16:18 -04:00
|
|
|
*
|
2017-01-11 21:37:53 -05:00
|
|
|
* @return void
|
|
|
|
*/
|
2017-07-25 16:11:02 -04:00
|
|
|
public function getMethodMutations($method_id, Context $this_context)
|
2017-01-11 21:37:53 -05:00
|
|
|
{
|
2017-01-12 00:54:41 -05:00
|
|
|
list($fq_class_name, $method_name) = explode('::', $method_id);
|
2017-06-30 01:24:45 -04:00
|
|
|
|
2017-07-25 16:11:02 -04:00
|
|
|
if (isset($this->class_checkers_to_analyze[strtolower($fq_class_name)])) {
|
|
|
|
$class_checker_to_examine = $this->class_checkers_to_analyze[strtolower($fq_class_name)];
|
|
|
|
} else {
|
2017-06-30 01:24:45 -04:00
|
|
|
$this->project_checker->getMethodMutations($method_id, $this_context);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$call_context = new Context($this_context->self);
|
2017-01-11 21:37:53 -05:00
|
|
|
$call_context->collect_mutations = true;
|
2018-01-24 13:38:53 -05:00
|
|
|
$call_context->collect_initializations = $this_context->collect_initializations;
|
|
|
|
$call_context->initialized_methods = $this_context->initialized_methods;
|
2017-06-30 01:24:45 -04:00
|
|
|
$call_context->include_location = $this_context->include_location;
|
2017-01-11 21:37:53 -05:00
|
|
|
|
2018-01-28 12:01:51 -05:00
|
|
|
foreach ($this_context->vars_possibly_in_scope as $var => $_) {
|
2017-01-11 21:37:53 -05:00
|
|
|
if (strpos($var, '$this->') === 0) {
|
|
|
|
$call_context->vars_possibly_in_scope[$var] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($this_context->vars_in_scope as $var => $type) {
|
|
|
|
if (strpos($var, '$this->') === 0) {
|
|
|
|
$call_context->vars_in_scope[$var] = $type;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$call_context->vars_in_scope['$this'] = $this_context->vars_in_scope['$this'];
|
|
|
|
|
2017-06-30 01:24:45 -04:00
|
|
|
$class_checker_to_examine->getMethodMutations($method_name, $call_context);
|
2017-01-12 00:54:41 -05:00
|
|
|
|
2017-01-18 23:19:36 -05:00
|
|
|
foreach ($call_context->vars_possibly_in_scope as $var => $_) {
|
2017-01-11 21:37:53 -05:00
|
|
|
$this_context->vars_possibly_in_scope[$var] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($call_context->vars_in_scope as $var => $type) {
|
|
|
|
$this_context->vars_in_scope[$var] = $type;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-26 18:42:48 -04:00
|
|
|
/**
|
2018-01-28 17:07:09 -05:00
|
|
|
* @return null|string
|
2016-04-26 18:42:48 -04:00
|
|
|
*/
|
2016-01-19 18:27:06 -05:00
|
|
|
public function getNamespace()
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-11-12 18:51:48 -05:00
|
|
|
/**
|
|
|
|
* @param string|null $namespace_name
|
2017-05-26 20:16:18 -04:00
|
|
|
*
|
2016-11-12 18:51:48 -05:00
|
|
|
* @return array<string, string>
|
|
|
|
*/
|
|
|
|
public function getAliasedClassesFlipped($namespace_name = null)
|
|
|
|
{
|
|
|
|
if ($namespace_name && isset($this->namespace_aliased_classes_flipped[$namespace_name])) {
|
|
|
|
return $this->namespace_aliased_classes_flipped[$namespace_name];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->aliased_classes_flipped;
|
|
|
|
}
|
|
|
|
|
2016-11-02 02:29:00 -04:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
2016-08-10 01:09:47 -04:00
|
|
|
public static function clearCache()
|
2016-03-23 13:05:25 -04:00
|
|
|
{
|
2016-12-08 15:57:18 -05:00
|
|
|
IssueBuffer::clearCache();
|
2018-01-05 19:49:27 -05:00
|
|
|
FileManipulationBuffer::clearCache();
|
2017-01-26 23:23:12 -07:00
|
|
|
FunctionLikeChecker::clearCache();
|
2018-01-21 12:44:46 -05:00
|
|
|
\Psalm\Provider\ClassLikeStorageProvider::deleteAll();
|
|
|
|
\Psalm\Provider\FileStorageProvider::deleteAll();
|
2016-05-10 14:00:44 -04:00
|
|
|
}
|
2016-11-06 00:59:29 -04:00
|
|
|
|
2017-01-07 14:35:07 -05:00
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getFileName()
|
|
|
|
{
|
|
|
|
return $this->file_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getFilePath()
|
|
|
|
{
|
|
|
|
return $this->file_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getCheckedFileName()
|
|
|
|
{
|
2018-05-22 23:38:27 -04:00
|
|
|
return $this->checked_file_names
|
|
|
|
? $this->checked_file_names[count($this->checked_file_names) - 1]
|
|
|
|
: $this->file_name;
|
2017-01-07 14:35:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getCheckedFilePath()
|
|
|
|
{
|
2018-05-22 23:38:27 -04:00
|
|
|
return $this->checked_file_paths
|
|
|
|
? $this->checked_file_paths[count($this->checked_file_paths) - 1]
|
|
|
|
: $this->file_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $file_path
|
|
|
|
* @param string $file_name
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function addCheckedFilePath($file_path, $file_name)
|
|
|
|
{
|
|
|
|
$this->included_file_paths[$file_path] = true;
|
|
|
|
$this->checked_file_names[] = $file_name;
|
|
|
|
$this->checked_file_paths[] = $file_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $file_path
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function removeCheckedFilePath($file_path)
|
|
|
|
{
|
|
|
|
if (!$this->checked_file_paths
|
|
|
|
|| $this->checked_file_paths[count($this->checked_file_paths) - 1] !== $file_path
|
|
|
|
) {
|
|
|
|
throw new \InvalidArgumentException($file_path . ' is not the most recently checked file');
|
|
|
|
}
|
|
|
|
|
|
|
|
array_pop($this->checked_file_paths);
|
|
|
|
array_pop($this->checked_file_names);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $file_path
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function hasNestedFilePath($file_path)
|
|
|
|
{
|
|
|
|
return $this->file_path === $file_path || in_array($file_path, $this->checked_file_paths);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $file_path
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function hasAlreadyIncludedFilePath($file_path)
|
|
|
|
{
|
|
|
|
return isset($this->included_file_paths[$file_path]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
public function getIncludeNesting()
|
|
|
|
{
|
|
|
|
return count($this->checked_file_paths);
|
2017-01-07 14:35:07 -05:00
|
|
|
}
|
|
|
|
|
2017-11-26 16:03:17 -05:00
|
|
|
/**
|
|
|
|
* @return array<int, string>
|
|
|
|
*/
|
2017-01-07 14:35:07 -05:00
|
|
|
public function getSuppressedIssues()
|
|
|
|
{
|
|
|
|
return $this->suppressed_issues;
|
|
|
|
}
|
|
|
|
|
2017-10-26 18:19:19 -04:00
|
|
|
/**
|
|
|
|
* @param array<int, string> $new_issues
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function addSuppressedIssues(array $new_issues)
|
|
|
|
{
|
|
|
|
$this->suppressed_issues = array_merge($new_issues, $this->suppressed_issues);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array<int, string> $new_issues
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function removeSuppressedIssues(array $new_issues)
|
|
|
|
{
|
|
|
|
$this->suppressed_issues = array_diff($this->suppressed_issues, $new_issues);
|
|
|
|
}
|
|
|
|
|
2017-11-26 16:03:17 -05:00
|
|
|
/**
|
2018-01-28 17:07:09 -05:00
|
|
|
* @return null|string
|
2017-11-26 16:03:17 -05:00
|
|
|
*/
|
2017-01-07 14:35:07 -05:00
|
|
|
public function getFQCLN()
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2017-11-26 16:03:17 -05:00
|
|
|
/**
|
2018-01-28 17:07:09 -05:00
|
|
|
* @return null|string
|
2017-11-26 16:03:17 -05:00
|
|
|
*/
|
2017-01-09 00:26:40 -05:00
|
|
|
public function getClassName()
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2017-11-26 16:03:17 -05:00
|
|
|
/**
|
|
|
|
* @return bool
|
|
|
|
*/
|
2017-01-07 14:35:07 -05:00
|
|
|
public function isStatic()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2017-03-19 23:30:20 -04:00
|
|
|
|
2017-11-26 16:03:17 -05:00
|
|
|
/**
|
|
|
|
* @return FileChecker
|
|
|
|
*/
|
2017-03-19 23:30:20 -04:00
|
|
|
public function getFileChecker()
|
|
|
|
{
|
|
|
|
return $this;
|
|
|
|
}
|
2016-01-07 18:28:27 -05:00
|
|
|
}
|