2016-06-05 20:25:16 -04:00
|
|
|
<?php
|
2016-07-25 18:37:44 -04:00
|
|
|
namespace Psalm;
|
2016-06-05 20:25:16 -04:00
|
|
|
|
2016-08-13 14:20:46 -04:00
|
|
|
use Psalm\Checker\ProjectChecker;
|
|
|
|
|
2016-06-26 15:18:40 -04:00
|
|
|
class IssueBuffer
|
2016-06-05 20:25:16 -04:00
|
|
|
{
|
2016-11-02 02:29:00 -04:00
|
|
|
/**
|
|
|
|
* @var array<int, string>
|
|
|
|
*/
|
2016-06-20 19:30:38 -04:00
|
|
|
protected static $errors = [];
|
2016-11-01 00:39:41 -04:00
|
|
|
|
2016-11-02 02:29:00 -04:00
|
|
|
/**
|
|
|
|
* @var array<string, bool>
|
|
|
|
*/
|
2016-10-18 18:55:53 -04:00
|
|
|
protected static $emitted = [];
|
2016-06-20 19:30:38 -04:00
|
|
|
|
2016-11-02 02:29:00 -04:00
|
|
|
/**
|
|
|
|
* @param Issue\CodeIssue $e
|
|
|
|
* @param array $suppressed_issues
|
|
|
|
* @return bool
|
|
|
|
*/
|
2016-07-22 13:29:46 -04:00
|
|
|
public static function accepts(Issue\CodeIssue $e, array $suppressed_issues = [])
|
2016-06-05 20:25:16 -04:00
|
|
|
{
|
2016-06-09 18:08:25 -04:00
|
|
|
$config = Config::getInstance();
|
|
|
|
|
2016-07-26 15:00:40 -04:00
|
|
|
$fqcn_parts = explode('\\', get_class($e));
|
|
|
|
$issue_type = array_pop($fqcn_parts);
|
2016-07-22 13:29:46 -04:00
|
|
|
|
|
|
|
if (in_array($issue_type, $suppressed_issues)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($config->excludeIssueInFile($issue_type, $e->getFileName())) {
|
2016-06-09 18:08:25 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-08 14:36:18 -04:00
|
|
|
return self::add($e);
|
2016-06-27 13:22:16 -04:00
|
|
|
}
|
|
|
|
|
2016-11-02 02:29:00 -04:00
|
|
|
/**
|
|
|
|
* @param Issue\CodeIssue $e
|
|
|
|
* @return bool
|
|
|
|
* @throws Exception\CodeException
|
|
|
|
*/
|
2016-06-27 13:22:16 -04:00
|
|
|
public static function add(Issue\CodeIssue $e)
|
|
|
|
{
|
|
|
|
$config = Config::getInstance();
|
|
|
|
|
2016-07-26 15:00:40 -04:00
|
|
|
$fqcn_parts = explode('\\', get_class($e));
|
|
|
|
$issue_type = array_pop($fqcn_parts);
|
2016-06-17 17:34:52 -04:00
|
|
|
|
2016-07-26 15:00:40 -04:00
|
|
|
$error_message = $issue_type . ' - ' . $e->getMessage();
|
2016-07-22 13:29:46 -04:00
|
|
|
|
|
|
|
$reporting_level = $config->getReportingLevel($issue_type);
|
2016-06-26 22:03:37 -04:00
|
|
|
|
|
|
|
switch ($reporting_level) {
|
|
|
|
case Config::REPORT_INFO:
|
2016-10-18 18:55:53 -04:00
|
|
|
if (ProjectChecker::$show_info && !self::alreadyEmitted($error_message)) {
|
2016-08-04 14:38:43 -04:00
|
|
|
echo 'INFO: ' . $error_message . PHP_EOL;
|
|
|
|
}
|
2016-06-26 22:03:37 -04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
case Config::REPORT_SUPPRESS:
|
|
|
|
return false;
|
2016-06-10 14:47:44 -04:00
|
|
|
}
|
|
|
|
|
2016-06-26 22:40:57 -04:00
|
|
|
if ($config->throw_exception) {
|
|
|
|
throw new Exception\CodeException($error_message);
|
|
|
|
}
|
|
|
|
|
2016-10-18 18:55:53 -04:00
|
|
|
if (!self::alreadyEmitted($error_message)) {
|
2016-11-02 02:29:00 -04:00
|
|
|
echo (ProjectChecker::$use_color ? "\033[0;31m" : '') . 'ERROR: ' .
|
|
|
|
(ProjectChecker::$use_color ? "\033[0m" : '') . $error_message . PHP_EOL;
|
2016-10-18 18:55:53 -04:00
|
|
|
}
|
2016-06-16 19:02:29 -04:00
|
|
|
|
2016-06-20 19:30:38 -04:00
|
|
|
if ($config->stop_on_first_error) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
self::$errors[] = $error_message;
|
2016-08-08 14:36:18 -04:00
|
|
|
|
|
|
|
return true;
|
2016-06-05 20:25:16 -04:00
|
|
|
}
|
2016-06-20 19:30:38 -04:00
|
|
|
|
2016-11-02 02:29:00 -04:00
|
|
|
/**
|
|
|
|
* @param bool $is_full
|
|
|
|
* @return void
|
|
|
|
*/
|
2016-10-07 00:58:08 -04:00
|
|
|
public static function finish($is_full = false)
|
2016-06-20 19:30:38 -04:00
|
|
|
{
|
2016-10-05 13:24:46 -04:00
|
|
|
Checker\FileChecker::updateReferenceCache();
|
|
|
|
|
2016-06-20 19:30:38 -04:00
|
|
|
if (count(self::$errors)) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2016-10-07 00:58:08 -04:00
|
|
|
|
|
|
|
if ($is_full) {
|
|
|
|
Checker\FileChecker::goodRun();
|
|
|
|
}
|
2016-06-20 19:30:38 -04:00
|
|
|
}
|
2016-10-18 18:55:53 -04:00
|
|
|
|
2016-10-30 12:46:18 -04:00
|
|
|
/**
|
|
|
|
* @param string $message
|
|
|
|
* @return bool
|
|
|
|
*/
|
2016-10-18 18:55:53 -04:00
|
|
|
protected static function alreadyEmitted($message)
|
|
|
|
{
|
|
|
|
$sham = sha1($message);
|
|
|
|
|
|
|
|
if (isset(self::$emitted[$sham])) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
self::$emitted[$sham] = true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2016-06-05 20:25:16 -04:00
|
|
|
}
|