2016-06-06 07:07:50 +02:00
|
|
|
<?php
|
2016-07-26 00:37:44 +02:00
|
|
|
namespace Psalm;
|
2016-06-06 07:07:50 +02:00
|
|
|
|
2016-08-13 20:20:46 +02:00
|
|
|
use Psalm\Checker\FileChecker;
|
2016-12-30 02:07:42 +01:00
|
|
|
use Psalm\Config\IssueHandler;
|
|
|
|
use Psalm\Config\ProjectFileFilter;
|
2016-11-02 07:29:00 +01:00
|
|
|
use Psalm\Exception\ConfigException;
|
2016-06-10 00:08:25 +02:00
|
|
|
use SimpleXMLElement;
|
|
|
|
|
2016-06-06 07:07:50 +02:00
|
|
|
class Config
|
|
|
|
{
|
2016-07-26 00:39:36 +02:00
|
|
|
const DEFAULT_FILE_NAME = 'psalm.xml';
|
2016-06-25 00:18:11 +02:00
|
|
|
const REPORT_INFO = 'info';
|
|
|
|
const REPORT_ERROR = 'error';
|
2016-06-26 19:45:20 +02:00
|
|
|
const REPORT_SUPPRESS = 'suppress';
|
2016-06-25 00:18:11 +02:00
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @var array<string>
|
|
|
|
*/
|
2016-06-27 21:10:13 +02:00
|
|
|
public static $ERROR_LEVELS = [
|
2016-06-25 00:18:11 +02:00
|
|
|
self::REPORT_INFO,
|
|
|
|
self::REPORT_ERROR,
|
2016-06-26 19:45:20 +02:00
|
|
|
self::REPORT_SUPPRESS
|
2016-06-25 00:18:11 +02:00
|
|
|
];
|
|
|
|
|
2016-12-19 01:17:39 +01:00
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected static $MIXED_ISSUES = [
|
|
|
|
'MixedArgument',
|
|
|
|
'MixedArrayAccess',
|
|
|
|
'MixedArrayOffset',
|
|
|
|
'MixedAssignment',
|
|
|
|
'MixedInferredReturnType',
|
|
|
|
'MixedMethodCall',
|
2016-12-24 03:30:32 +01:00
|
|
|
'MixedOperand',
|
2016-12-19 01:17:39 +01:00
|
|
|
'MixedPropertyFetch',
|
|
|
|
'MixedPropertyAssignment',
|
|
|
|
'MixedStringOffsetAssignment'
|
|
|
|
];
|
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @var self|null
|
|
|
|
*/
|
|
|
|
protected static $config;
|
2016-06-10 00:08:25 +02:00
|
|
|
|
2016-06-27 04:40:57 +02:00
|
|
|
/**
|
|
|
|
* Whether or not to stop when the first error is seen
|
2016-11-01 05:39:41 +01:00
|
|
|
*
|
2016-06-27 04:40:57 +02:00
|
|
|
* @var boolean
|
|
|
|
*/
|
2016-06-21 01:30:38 +02:00
|
|
|
public $stop_on_first_error = true;
|
2016-06-27 04:40:57 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether or not to use types as defined in docblocks
|
2016-11-01 05:39:41 +01:00
|
|
|
*
|
2016-06-27 04:40:57 +02:00
|
|
|
* @var boolean
|
|
|
|
*/
|
2016-08-24 06:22:38 +02:00
|
|
|
public $use_docblock_types = true;
|
2016-06-10 00:08:25 +02:00
|
|
|
|
2016-06-27 04:40:57 +02:00
|
|
|
/**
|
|
|
|
* Whether or not to throw an exception on first error
|
2016-11-01 05:39:41 +01:00
|
|
|
*
|
2016-06-27 04:40:57 +02:00
|
|
|
* @var boolean
|
|
|
|
*/
|
|
|
|
public $throw_exception = false;
|
|
|
|
|
2016-07-26 21:00:40 +02:00
|
|
|
/**
|
2016-11-04 22:45:12 +01:00
|
|
|
* The directory to store PHP Parser (and other) caches
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
public $cache_directory = '/var/tmp/psalm';
|
|
|
|
|
2016-12-05 00:43:07 +01:00
|
|
|
/**
|
|
|
|
* Whether or not to use property defaults to inform type when none is listed
|
|
|
|
*
|
|
|
|
* @var boolean
|
|
|
|
*/
|
|
|
|
public $use_property_default_for_type = true;
|
|
|
|
|
2016-11-04 22:45:12 +01:00
|
|
|
/**
|
|
|
|
* Path to the autoader
|
2016-11-01 05:39:41 +01:00
|
|
|
*
|
2016-07-26 21:00:40 +02:00
|
|
|
* @var string|null
|
|
|
|
*/
|
|
|
|
public $autoloader;
|
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
2016-12-30 02:07:42 +01:00
|
|
|
* @var ProjectFileFilter|null
|
2016-11-02 07:29:00 +01:00
|
|
|
*/
|
2016-12-29 14:42:39 +01:00
|
|
|
protected $project_files;
|
2016-06-10 00:08:25 +02:00
|
|
|
|
2016-09-01 05:12:35 +02:00
|
|
|
/**
|
|
|
|
* The base directory of this config file
|
2016-11-01 05:39:41 +01:00
|
|
|
*
|
2016-09-01 05:12:35 +02:00
|
|
|
* @var string
|
|
|
|
*/
|
2016-06-10 20:47:44 +02:00
|
|
|
protected $base_dir;
|
2016-06-06 07:07:50 +02:00
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @var array<int, string>
|
|
|
|
*/
|
2016-06-10 20:47:44 +02:00
|
|
|
protected $file_extensions = ['php'];
|
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @var array<int, string>
|
|
|
|
*/
|
2016-06-20 06:38:13 +02:00
|
|
|
protected $filetype_handlers = [];
|
|
|
|
|
2016-09-09 22:21:49 +02:00
|
|
|
/**
|
2016-12-30 02:07:42 +01:00
|
|
|
* @var array<string, IssueHandler>
|
2016-09-09 22:21:49 +02:00
|
|
|
*/
|
2016-06-10 20:47:44 +02:00
|
|
|
protected $issue_handlers = [];
|
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @var array<int, string>
|
|
|
|
*/
|
2016-06-10 20:47:44 +02:00
|
|
|
protected $mock_classes = [];
|
2016-06-06 07:07:50 +02:00
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @var boolean
|
|
|
|
*/
|
2016-09-01 05:12:35 +02:00
|
|
|
public $hide_external_errors = true;
|
|
|
|
|
2016-12-07 00:27:22 +01:00
|
|
|
/** @var bool */
|
2016-12-06 22:41:42 +01:00
|
|
|
public $allow_includes = true;
|
|
|
|
|
2016-12-19 01:17:39 +01:00
|
|
|
/** @var bool */
|
|
|
|
public $totally_typed = false;
|
|
|
|
|
2016-12-24 03:30:32 +01:00
|
|
|
/** @var bool */
|
|
|
|
public $strict_binary_operands = false;
|
|
|
|
|
2016-06-18 20:45:55 +02:00
|
|
|
/**
|
2016-07-26 00:37:44 +02:00
|
|
|
* Psalm plugins
|
2016-11-02 07:29:00 +01:00
|
|
|
*
|
2016-06-18 20:45:55 +02:00
|
|
|
* @var array<Plugin>
|
|
|
|
*/
|
|
|
|
protected $plugins = [];
|
|
|
|
|
2016-11-21 03:49:06 +01:00
|
|
|
/** @var array<string, mixed> */
|
|
|
|
protected $predefined_constants;
|
|
|
|
|
2016-12-14 18:28:38 +01:00
|
|
|
protected function __construct()
|
2016-06-06 07:07:50 +02:00
|
|
|
{
|
2016-11-02 07:29:00 +01:00
|
|
|
self::$config = $this;
|
2016-06-06 07:07:50 +02:00
|
|
|
}
|
|
|
|
|
2016-06-26 19:45:20 +02:00
|
|
|
/**
|
|
|
|
* Creates a new config object from the file
|
2016-11-02 07:29:00 +01:00
|
|
|
*
|
2016-12-29 16:24:10 +01:00
|
|
|
* @param string $file_path
|
|
|
|
* @return self
|
|
|
|
*/
|
|
|
|
public static function loadFromXMLFile($file_path)
|
|
|
|
{
|
|
|
|
$file_contents = file_get_contents($file_path);
|
|
|
|
|
|
|
|
if ($file_contents === false) {
|
|
|
|
throw new \InvalidArgumentException('Cannot open ' . $file_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return self::loadFromXML($file_path, $file_contents);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a new config object from an XML string
|
|
|
|
*
|
|
|
|
* @param string $file_path
|
|
|
|
* @param string $file_contents
|
2016-11-01 05:39:41 +01:00
|
|
|
* @return self
|
2016-11-05 02:14:04 +01:00
|
|
|
* @psalm-suppress MixedArgument
|
|
|
|
* @psalm-suppress MixedPropertyFetch
|
|
|
|
* @psalm-suppress MixedMethodCall
|
2016-12-17 06:48:31 +01:00
|
|
|
* @psalm-suppress MixedAssignment
|
2016-12-24 12:03:55 +01:00
|
|
|
* @psalm-suppress MixedOperand
|
2016-06-26 19:45:20 +02:00
|
|
|
*/
|
2016-12-29 16:24:10 +01:00
|
|
|
public static function loadFromXML($file_path, $file_contents)
|
2016-06-10 00:08:25 +02:00
|
|
|
{
|
2016-06-21 01:30:38 +02:00
|
|
|
$config = new self();
|
|
|
|
|
2016-12-29 16:24:10 +01:00
|
|
|
$config->base_dir = dirname($file_path) . '/';
|
2016-06-10 20:47:44 +02:00
|
|
|
|
2016-06-10 00:08:25 +02:00
|
|
|
$config_xml = new SimpleXMLElement($file_contents);
|
|
|
|
|
2016-06-21 01:30:38 +02:00
|
|
|
if (isset($config_xml['stopOnFirstError'])) {
|
2016-10-24 05:32:17 +02:00
|
|
|
$attribute_text = (string) $config_xml['stopOnFirstError'];
|
2016-06-21 01:30:38 +02:00
|
|
|
$config->stop_on_first_error = $attribute_text === 'true' || $attribute_text === '1';
|
2016-06-10 00:08:25 +02:00
|
|
|
}
|
|
|
|
|
2016-06-25 00:18:11 +02:00
|
|
|
if (isset($config_xml['useDocblockTypes'])) {
|
|
|
|
$attribute_text = (string) $config_xml['useDocblockTypes'];
|
|
|
|
$config->use_docblock_types = $attribute_text === 'true' || $attribute_text === '1';
|
2016-06-10 00:08:25 +02:00
|
|
|
}
|
|
|
|
|
2016-06-27 04:40:57 +02:00
|
|
|
if (isset($config_xml['throwExceptionOnError'])) {
|
|
|
|
$attribute_text = (string) $config_xml['throwExceptionOnError'];
|
|
|
|
$config->throw_exception = $attribute_text === 'true' || $attribute_text === '1';
|
|
|
|
}
|
|
|
|
|
2016-09-01 05:12:35 +02:00
|
|
|
if (isset($config_xml['hideExternalErrors'])) {
|
|
|
|
$attribute_text = (string) $config_xml['hideExternalErrors'];
|
|
|
|
$config->hide_external_errors = $attribute_text === 'true' || $attribute_text === '1';
|
|
|
|
}
|
|
|
|
|
2016-07-26 21:00:40 +02:00
|
|
|
if (isset($config_xml['autoloader'])) {
|
|
|
|
$config->autoloader = (string) $config_xml['autoloader'];
|
|
|
|
}
|
|
|
|
|
2016-11-04 22:45:12 +01:00
|
|
|
if (isset($config_xml['cacheDirectory'])) {
|
2016-11-05 02:14:04 +01:00
|
|
|
$config->cache_directory = (string) $config_xml['cacheDirectory'];
|
2016-11-04 22:45:12 +01:00
|
|
|
}
|
|
|
|
|
2016-12-05 00:43:07 +01:00
|
|
|
if (isset($config_xml['cacheDirectory'])) {
|
|
|
|
$config->cache_directory = (string) $config_xml['cacheDirectory'];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($config_xml['usePropertyDefaultForType'])) {
|
|
|
|
$attribute_text = (string) $config_xml['usePropertyDefaultForType'];
|
|
|
|
$config->use_property_default_for_type = $attribute_text === 'true' || $attribute_text === '1';
|
|
|
|
}
|
|
|
|
|
2016-12-06 22:41:42 +01:00
|
|
|
if (isset($config_xml['allowFileIncludes'])) {
|
|
|
|
$attribute_text = (string) $config_xml['allowFileIncludes'];
|
|
|
|
$config->allow_includes = $attribute_text === 'true' || $attribute_text === '1';
|
|
|
|
}
|
|
|
|
|
2016-12-19 01:17:39 +01:00
|
|
|
if (isset($config_xml['totallyTyped'])) {
|
|
|
|
$attribute_text = (string) $config_xml['totallyTyped'];
|
|
|
|
$config->totally_typed = $attribute_text === 'true' || $attribute_text === '1';
|
|
|
|
}
|
|
|
|
|
2016-12-24 03:30:32 +01:00
|
|
|
if (isset($config_xml['strictBinaryOperands'])) {
|
|
|
|
$attribute_text = (string) $config_xml['strictBinaryOperands'];
|
|
|
|
$config->strict_binary_operands = $attribute_text === 'true' || $attribute_text === '1';
|
|
|
|
}
|
|
|
|
|
2016-12-29 14:42:39 +01:00
|
|
|
if (isset($config_xml->projectFiles)) {
|
2016-12-30 02:07:42 +01:00
|
|
|
$config->project_files = ProjectFileFilter::loadFromXMLElement($config_xml->projectFiles, true);
|
2016-06-10 00:08:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($config_xml->fileExtensions)) {
|
2016-06-21 01:30:38 +02:00
|
|
|
$config->file_extensions = [];
|
2016-06-10 20:47:44 +02:00
|
|
|
|
2016-06-21 01:30:38 +02:00
|
|
|
$config->loadFileExtensions($config_xml->fileExtensions->extension);
|
2016-06-10 20:47:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($config_xml->mockClasses) && isset($config_xml->mockClasses->class)) {
|
2016-11-22 01:07:56 +01:00
|
|
|
/** @var \SimpleXMLElement $mock_class */
|
2016-06-10 20:47:44 +02:00
|
|
|
foreach ($config_xml->mockClasses->class as $mock_class) {
|
2016-06-21 01:30:38 +02:00
|
|
|
$config->mock_classes[] = $mock_class['name'];
|
2016-06-10 00:08:25 +02:00
|
|
|
}
|
2016-06-10 20:47:44 +02:00
|
|
|
}
|
|
|
|
|
2016-06-18 20:45:55 +02:00
|
|
|
// this plugin loading system borrows heavily from etsy/phan
|
|
|
|
if (isset($config_xml->plugins) && isset($config_xml->plugins->plugin)) {
|
2016-11-22 01:07:56 +01:00
|
|
|
/** @var \SimpleXMLElement $plugin */
|
2016-06-18 20:45:55 +02:00
|
|
|
foreach ($config_xml->plugins->plugin as $plugin) {
|
|
|
|
$plugin_file_name = $plugin['filename'];
|
2016-06-20 06:38:13 +02:00
|
|
|
|
2016-06-21 01:30:38 +02:00
|
|
|
$path = $config->base_dir . $plugin_file_name;
|
2016-06-20 06:38:13 +02:00
|
|
|
|
|
|
|
if (!file_exists($path)) {
|
|
|
|
throw new \InvalidArgumentException('Cannot find file ' . $path);
|
|
|
|
}
|
|
|
|
|
|
|
|
$loaded_plugin = require($path);
|
2016-06-18 20:45:55 +02:00
|
|
|
|
|
|
|
if (!$loaded_plugin) {
|
2016-11-02 07:29:00 +01:00
|
|
|
throw new \InvalidArgumentException(
|
|
|
|
'Plugins must return an instance of that plugin at the end of the file - ' .
|
|
|
|
$plugin_file_name . ' does not'
|
|
|
|
);
|
2016-06-18 20:45:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!($loaded_plugin instanceof Plugin)) {
|
2016-11-02 07:29:00 +01:00
|
|
|
throw new \InvalidArgumentException(
|
|
|
|
'Plugins must extend \Psalm\Plugin - ' . $plugin_file_name . ' does not'
|
|
|
|
);
|
2016-06-18 20:45:55 +02:00
|
|
|
}
|
|
|
|
|
2016-06-21 01:30:38 +02:00
|
|
|
$config->plugins[] = $loaded_plugin;
|
2016-06-18 20:45:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-30 02:07:42 +01:00
|
|
|
if (isset($config_xml->issueHandlers)) {
|
2016-11-22 01:07:56 +01:00
|
|
|
/** @var \SimpleXMLElement $issue_handler */
|
2016-12-30 02:07:42 +01:00
|
|
|
foreach ($config_xml->issueHandlers->children() as $key => $issue_handler) {
|
|
|
|
$config->issue_handlers[$key] = IssueHandler::loadFromXMLElement(
|
|
|
|
$issue_handler
|
|
|
|
);
|
2016-06-10 00:08:25 +02:00
|
|
|
}
|
|
|
|
}
|
2016-06-26 19:45:20 +02:00
|
|
|
|
|
|
|
return $config;
|
2016-06-10 00:08:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return $this
|
|
|
|
*/
|
2016-06-06 07:07:50 +02:00
|
|
|
public static function getInstance()
|
|
|
|
{
|
2016-11-02 07:29:00 +01:00
|
|
|
if (self::$config) {
|
|
|
|
return self::$config;
|
2016-06-06 07:07:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return new self();
|
|
|
|
}
|
|
|
|
|
2016-12-09 04:37:59 +01:00
|
|
|
/**
|
|
|
|
* @param string $issue_key
|
|
|
|
* @param string $error_level
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function setCustomErrorLevel($issue_key, $error_level)
|
|
|
|
{
|
2016-12-30 02:07:42 +01:00
|
|
|
$this->issue_handlers[$issue_key] = new IssueHandler();
|
|
|
|
$this->issue_handlers[$issue_key]->setErrorLevel($error_level);
|
2016-12-09 04:37:59 +01:00
|
|
|
}
|
|
|
|
|
2016-10-30 17:46:18 +01:00
|
|
|
/**
|
|
|
|
* @param array<\SimpleXMLElement> $extensions
|
|
|
|
* @return void
|
2016-11-02 07:29:00 +01:00
|
|
|
* @throws ConfigException If a Config file could not be found.
|
2016-11-22 01:07:56 +01:00
|
|
|
* @psalm-suppress MixedArrayAccess
|
2016-12-17 06:48:31 +01:00
|
|
|
* @psalm-suppress MixedAssignment
|
2016-12-24 12:03:55 +01:00
|
|
|
* @psalm-suppress MixedOperand
|
2016-10-30 17:46:18 +01:00
|
|
|
*/
|
2016-06-20 06:38:13 +02:00
|
|
|
protected function loadFileExtensions($extensions)
|
|
|
|
{
|
|
|
|
foreach ($extensions as $extension) {
|
2016-11-05 02:14:04 +01:00
|
|
|
$extension_name = preg_replace('/^\.?/', '', (string)$extension['name']);
|
2016-06-20 06:38:13 +02:00
|
|
|
$this->file_extensions[] = $extension_name;
|
|
|
|
|
|
|
|
if (isset($extension['filetypeHandler'])) {
|
2016-12-24 12:03:55 +01:00
|
|
|
$path = $this->base_dir . (string)$extension['filetypeHandler'];
|
2016-06-20 06:38:13 +02:00
|
|
|
|
|
|
|
if (!file_exists($path)) {
|
2016-06-20 07:05:44 +02:00
|
|
|
throw new Exception\ConfigException('Error parsing config: cannot find file ' . $path);
|
2016-06-20 06:38:13 +02:00
|
|
|
}
|
|
|
|
|
2016-12-17 06:48:31 +01:00
|
|
|
$declared_classes = FileChecker::getDeclaredClassesInFile($path);
|
2016-06-20 06:38:13 +02:00
|
|
|
|
|
|
|
if (count($declared_classes) !== 1) {
|
2016-11-02 07:29:00 +01:00
|
|
|
throw new \InvalidArgumentException(
|
|
|
|
'Filetype handlers must have exactly one class in the file - ' . $path . ' has ' .
|
|
|
|
count($declared_classes)
|
|
|
|
);
|
2016-06-20 06:38:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
require_once($path);
|
|
|
|
|
2016-08-13 20:20:46 +02:00
|
|
|
if (!is_subclass_of($declared_classes[0], 'Psalm\\Checker\\FileChecker')) {
|
2016-11-02 07:29:00 +01:00
|
|
|
throw new \InvalidArgumentException(
|
|
|
|
'Filetype handlers must extend \Psalm\Checker\FileChecker - ' . $path . ' does not'
|
|
|
|
);
|
2016-06-20 06:38:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->filetype_handlers[$extension_name] = $declared_classes[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-09 23:55:21 +02:00
|
|
|
/**
|
|
|
|
* @param string $file_name
|
|
|
|
* @return string
|
|
|
|
*/
|
2016-06-10 23:20:04 +02:00
|
|
|
public function shortenFileName($file_name)
|
|
|
|
{
|
|
|
|
return preg_replace('/^' . preg_quote($this->base_dir, '/') . '/', '', $file_name);
|
|
|
|
}
|
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @param string $issue_type
|
|
|
|
* @param string $file_name
|
|
|
|
* @return bool
|
|
|
|
*/
|
2016-06-10 00:08:25 +02:00
|
|
|
public function excludeIssueInFile($issue_type, $file_name)
|
|
|
|
{
|
2016-12-19 01:17:39 +01:00
|
|
|
if (!$this->totally_typed && in_array($issue_type, self::$MIXED_ISSUES)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-06-10 23:20:04 +02:00
|
|
|
$file_name = $this->shortenFileName($file_name);
|
2016-06-10 20:47:44 +02:00
|
|
|
|
2016-12-30 00:33:03 +01:00
|
|
|
if ($this->project_files && $this->hide_external_errors) {
|
2016-09-01 05:12:35 +02:00
|
|
|
if (!$this->isInProjectDirs($file_name)) {
|
2016-08-05 21:11:20 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-30 02:07:42 +01:00
|
|
|
if ($this->getReportingLevelForFile($issue_type, $file_name) === self::REPORT_SUPPRESS) {
|
|
|
|
return true;
|
2016-06-10 20:47:44 +02:00
|
|
|
}
|
2016-06-10 00:08:25 +02:00
|
|
|
|
2016-12-30 02:07:42 +01:00
|
|
|
return false;
|
2016-06-10 00:08:25 +02:00
|
|
|
}
|
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @param string $file_name
|
|
|
|
* @return bool
|
|
|
|
*/
|
2016-09-01 05:12:35 +02:00
|
|
|
public function isInProjectDirs($file_name)
|
|
|
|
{
|
2016-12-30 00:33:03 +01:00
|
|
|
return $this->project_files && $this->project_files->allows($file_name);
|
2016-09-01 05:12:35 +02:00
|
|
|
}
|
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @param string $issue_type
|
2016-12-30 02:07:42 +01:00
|
|
|
* @param string $file_name
|
2016-11-02 07:29:00 +01:00
|
|
|
* @return string
|
|
|
|
*/
|
2016-12-30 02:07:42 +01:00
|
|
|
public function getReportingLevelForFile($issue_type, $file_name)
|
2016-06-21 01:30:38 +02:00
|
|
|
{
|
2016-12-30 02:07:42 +01:00
|
|
|
if (isset($this->issue_handlers[$issue_type])) {
|
|
|
|
return $this->issue_handlers[$issue_type]->getReportingLevelForFile($file_name);
|
2016-06-21 01:30:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return self::REPORT_ERROR;
|
|
|
|
}
|
|
|
|
|
2016-10-15 06:12:57 +02:00
|
|
|
/**
|
|
|
|
* @return array<string>
|
|
|
|
*/
|
2016-12-29 16:24:10 +01:00
|
|
|
public function getProjectDirectories()
|
2016-06-10 00:08:25 +02:00
|
|
|
{
|
2016-12-29 14:42:39 +01:00
|
|
|
if (!$this->project_files) {
|
2016-08-07 02:27:13 +02:00
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
2016-12-29 16:24:10 +01:00
|
|
|
return $this->project_files->getDirectories();
|
2016-06-13 21:33:18 +02:00
|
|
|
}
|
2016-06-10 00:08:25 +02:00
|
|
|
|
2016-10-23 18:24:53 +02:00
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
2016-06-13 21:33:18 +02:00
|
|
|
public function getBaseDir()
|
|
|
|
{
|
|
|
|
return $this->base_dir;
|
|
|
|
}
|
2016-06-10 00:08:25 +02:00
|
|
|
|
2016-10-15 06:12:57 +02:00
|
|
|
/**
|
|
|
|
* @return array<string>
|
|
|
|
*/
|
2016-06-13 21:33:18 +02:00
|
|
|
public function getFileExtensions()
|
|
|
|
{
|
|
|
|
return $this->file_extensions;
|
2016-06-10 00:08:25 +02:00
|
|
|
}
|
2016-06-10 20:47:44 +02:00
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
2016-06-20 06:38:13 +02:00
|
|
|
public function getFiletypeHandlers()
|
|
|
|
{
|
|
|
|
return $this->filetype_handlers;
|
|
|
|
}
|
|
|
|
|
2016-10-09 23:55:21 +02:00
|
|
|
/**
|
2016-11-01 05:39:41 +01:00
|
|
|
* @return array<int, string>
|
2016-10-09 23:55:21 +02:00
|
|
|
*/
|
2016-06-10 20:47:44 +02:00
|
|
|
public function getMockClasses()
|
|
|
|
{
|
|
|
|
return $this->mock_classes;
|
|
|
|
}
|
2016-06-18 20:45:55 +02:00
|
|
|
|
2016-11-04 22:45:12 +01:00
|
|
|
/**
|
2016-11-05 02:14:04 +01:00
|
|
|
* @return string
|
2016-11-04 22:45:12 +01:00
|
|
|
*/
|
|
|
|
public function getCacheDirectory()
|
|
|
|
{
|
|
|
|
return $this->cache_directory;
|
|
|
|
}
|
|
|
|
|
2016-10-09 23:55:21 +02:00
|
|
|
/**
|
|
|
|
* @return array<Plugin>
|
|
|
|
*/
|
2016-06-18 20:45:55 +02:00
|
|
|
public function getPlugins()
|
|
|
|
{
|
|
|
|
return $this->plugins;
|
|
|
|
}
|
2016-06-20 22:18:31 +02:00
|
|
|
|
2016-11-02 07:29:00 +01:00
|
|
|
/**
|
|
|
|
* @param string $issue_name
|
2016-12-30 02:07:42 +01:00
|
|
|
* @param IssueHandler|null $handler
|
2016-11-02 07:29:00 +01:00
|
|
|
* @return void
|
|
|
|
*/
|
2016-12-30 02:07:42 +01:00
|
|
|
public function setIssueHandler($issue_name, IssueHandler $handler = null)
|
2016-06-20 22:18:31 +02:00
|
|
|
{
|
2016-12-30 02:07:42 +01:00
|
|
|
$this->issue_handlers[$issue_name] = $handler;
|
2016-06-20 22:18:31 +02:00
|
|
|
}
|
2016-11-21 03:49:06 +01:00
|
|
|
|
2016-11-21 05:45:10 +01:00
|
|
|
/**
|
|
|
|
* @return array<string, mixed>
|
|
|
|
*/
|
2016-11-21 03:49:06 +01:00
|
|
|
public function getPredefinedConstants()
|
|
|
|
{
|
|
|
|
return $this->predefined_constants;
|
|
|
|
}
|
|
|
|
|
2016-11-21 05:45:10 +01:00
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
2016-11-21 03:49:06 +01:00
|
|
|
public function collectPredefinedConstants()
|
|
|
|
{
|
|
|
|
$this->predefined_constants = get_defined_constants();
|
|
|
|
}
|
2016-06-06 07:07:50 +02:00
|
|
|
}
|