diff --git a/config.xsd b/config.xsd index 50a69fc0c..8955d3653 100644 --- a/config.xsd +++ b/config.xsd @@ -46,7 +46,7 @@ - + @@ -63,6 +63,11 @@ + + + + + diff --git a/src/Psalm/Codebase/Analyzer.php b/src/Psalm/Codebase/Analyzer.php index 24d17697c..e20741cd9 100644 --- a/src/Psalm/Codebase/Analyzer.php +++ b/src/Psalm/Codebase/Analyzer.php @@ -306,6 +306,10 @@ class Analyzer } foreach ($all_deep_scanned_files as $file_path => $_) { + if (!$this->config->reportTypeStatsForFile($file_path)) { + continue; + } + if (isset($this->mixed_counts[$file_path])) { list($path_mixed_count, $path_nonmixed_count) = $this->mixed_counts[$file_path]; $mixed_count += $path_mixed_count; @@ -342,6 +346,10 @@ class Analyzer foreach ($this->files_to_analyze as $file_path => $_) { $all_deep_scanned_files[$file_path] = true; + if (!$this->config->reportTypeStatsForFile($file_path)) { + continue; + } + foreach ($this->file_storage_provider->get($file_path)->required_file_paths as $required_file_path) { $all_deep_scanned_files[$required_file_path] = true; } diff --git a/src/Psalm/Config.php b/src/Psalm/Config.php index 5c4b8a445..00f168cee 100644 --- a/src/Psalm/Config.php +++ b/src/Psalm/Config.php @@ -983,6 +983,16 @@ class Config return $this->project_files->getFiles(); } + /** + * @param string $file_path + * + * @return bool + */ + public function reportTypeStatsForFile($file_path) + { + return $this->project_files && $this->project_files->reportTypeStats($file_path); + } + /** * @return array */ diff --git a/src/Psalm/Config/FileFilter.php b/src/Psalm/Config/FileFilter.php index 2be1e23a9..401584832 100644 --- a/src/Psalm/Config/FileFilter.php +++ b/src/Psalm/Config/FileFilter.php @@ -40,6 +40,11 @@ class FileFilter */ protected $inclusive; + /** + * @var array + */ + protected $ignore_type_stats = []; + /** * @param bool $inclusive * @@ -72,6 +77,9 @@ class FileFilter /** @var \SimpleXMLElement $directory */ foreach ($e->directory as $directory) { $directory_path = (string) $directory['name']; + $ignore_type_stats = strtolower( + isset($directory['ignoreTypeStats']) ? (string) $directory['ignoreTypeStats'] : '' + ) === 'true'; if ($directory_path[0] === '/' && DIRECTORY_SEPARATOR === '/') { $prospective_directory_path = $directory_path; @@ -100,6 +108,11 @@ class FileFilter (string)$directory['name'] . ':' . $glob_index . PHP_EOL; exit(1); } + + if ($ignore_type_stats && $filter instanceof ProjectFileFilter) { + $filter->ignore_type_stats[$directory_path] = true; + } + $filter->addDirectory($directory_path); } continue; @@ -113,6 +126,10 @@ class FileFilter exit(1); } + if ($ignore_type_stats && $filter instanceof ProjectFileFilter) { + $filter->ignore_type_stats[$directory_path] = true; + } + $filter->addDirectory($directory_path); } } diff --git a/src/Psalm/Config/ProjectFileFilter.php b/src/Psalm/Config/ProjectFileFilter.php index 6714ca1a5..578661959 100644 --- a/src/Psalm/Config/ProjectFileFilter.php +++ b/src/Psalm/Config/ProjectFileFilter.php @@ -69,4 +69,27 @@ class ProjectFileFilter extends FileFilter return false; } + + /** + * @param string $file_name + * @param bool $case_sensitive + * + * @return bool + */ + public function reportTypeStats($file_name, $case_sensitive = false) + { + foreach ($this->ignore_type_stats as $exclude_dir => $_) { + if ($case_sensitive) { + if (strpos($file_name, $exclude_dir) === 0) { + return false; + } + } else { + if (stripos($file_name, $exclude_dir) === 0) { + return false; + } + } + } + + return true; + } }