1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Split up scanning into specific steps

This commit is contained in:
Brown 2018-10-10 16:59:03 -04:00
parent 870e242ec3
commit 7278feb811

View File

@ -251,74 +251,99 @@ class Scanner
*/
public function scanFiles(ClassLikes $classlikes)
{
$filetype_scanners = $this->config->getFiletypeScanners();
$has_changes = false;
while ($this->files_to_scan || $this->classes_to_scan) {
if ($this->files_to_scan) {
$file_path = array_shift($this->files_to_scan);
if (!isset($this->scanned_files[$file_path])
|| (isset($this->files_to_deep_scan[$file_path]) && !$this->scanned_files[$file_path])
) {
$this->scanFile(
$file_path,
$filetype_scanners,
isset($this->files_to_deep_scan[$file_path])
);
if ($this->scanFilePaths()) {
$has_changes = true;
}
} else {
$fq_classlike_name = array_shift($this->classes_to_scan);
$fq_classlike_name_lc = strtolower($fq_classlike_name);
if (isset($this->reflected_classlikes_lc[$fq_classlike_name_lc])) {
continue;
}
if ($classlikes->isMissingClassLike($fq_classlike_name_lc)) {
continue;
}
if (!isset($this->classlike_files[$fq_classlike_name_lc])) {
if ($classlikes->doesClassLikeExist($fq_classlike_name_lc)) {
if ($this->debug_output) {
echo 'Using reflection to get metadata for ' . $fq_classlike_name . "\n";
}
$reflected_class = new \ReflectionClass($fq_classlike_name);
$this->reflection->registerClass($reflected_class);
$this->reflected_classlikes_lc[$fq_classlike_name_lc] = true;
} elseif ($this->fileExistsForClassLike($classlikes, $fq_classlike_name)) {
// even though we've checked this above, calling the method invalidates it
if (isset($this->classlike_files[$fq_classlike_name_lc])) {
/** @var string */
$file_path = $this->classlike_files[$fq_classlike_name_lc];
$this->files_to_scan[$file_path] = $file_path;
if (isset($this->classes_to_deep_scan[$fq_classlike_name_lc])) {
unset($this->classes_to_deep_scan[$fq_classlike_name_lc]);
$this->files_to_deep_scan[$file_path] = $file_path;
}
}
} elseif ($this->store_scan_failure[$fq_classlike_name]) {
$classlikes->registerMissingClassLike($fq_classlike_name_lc);
}
} elseif (isset($this->classes_to_deep_scan[$fq_classlike_name_lc])
&& !isset($this->deep_scanned_classlike_files[$fq_classlike_name_lc])
) {
$file_path = $this->classlike_files[$fq_classlike_name_lc];
$this->files_to_scan[$file_path] = $file_path;
unset($this->classes_to_deep_scan[$fq_classlike_name_lc]);
$this->files_to_deep_scan[$file_path] = $file_path;
$this->deep_scanned_classlike_files[$fq_classlike_name_lc] = true;
}
$this->convertClassesToFilePaths($classlikes);
}
}
return $has_changes;
}
private function scanFilePaths() : bool
{
$filetype_scanners = $this->config->getFiletypeScanners();
$files_to_scan = $this->files_to_scan;
$has_changes = false;
$this->files_to_scan = [];
foreach ($files_to_scan as $file_path) {
if (!isset($this->scanned_files[$file_path])
|| (isset($this->files_to_deep_scan[$file_path]) && !$this->scanned_files[$file_path])
) {
$this->scanFile(
$file_path,
$filetype_scanners,
isset($this->files_to_deep_scan[$file_path])
);
$has_changes = true;
}
}
return $has_changes;
}
/**
* @return void
*/
private function convertClassesToFilePaths(ClassLikes $classlikes)
{
$classes_to_scan = $this->classes_to_scan;
$this->classes_to_scan = [];
foreach ($classes_to_scan as $fq_classlike_name) {
$fq_classlike_name_lc = strtolower($fq_classlike_name);
if (isset($this->reflected_classlikes_lc[$fq_classlike_name_lc])) {
continue;
}
if ($classlikes->isMissingClassLike($fq_classlike_name_lc)) {
continue;
}
if (!isset($this->classlike_files[$fq_classlike_name_lc])) {
if ($classlikes->doesClassLikeExist($fq_classlike_name_lc)) {
if ($this->debug_output) {
echo 'Using reflection to get metadata for ' . $fq_classlike_name . "\n";
}
$reflected_class = new \ReflectionClass($fq_classlike_name);
$this->reflection->registerClass($reflected_class);
$this->reflected_classlikes_lc[$fq_classlike_name_lc] = true;
} elseif ($this->fileExistsForClassLike($classlikes, $fq_classlike_name)) {
// even though we've checked this above, calling the method invalidates it
if (isset($this->classlike_files[$fq_classlike_name_lc])) {
/** @var string */
$file_path = $this->classlike_files[$fq_classlike_name_lc];
$this->files_to_scan[$file_path] = $file_path;
if (isset($this->classes_to_deep_scan[$fq_classlike_name_lc])) {
unset($this->classes_to_deep_scan[$fq_classlike_name_lc]);
$this->files_to_deep_scan[$file_path] = $file_path;
}
}
} elseif ($this->store_scan_failure[$fq_classlike_name]) {
$classlikes->registerMissingClassLike($fq_classlike_name_lc);
}
} elseif (isset($this->classes_to_deep_scan[$fq_classlike_name_lc])
&& !isset($this->deep_scanned_classlike_files[$fq_classlike_name_lc])
) {
$file_path = $this->classlike_files[$fq_classlike_name_lc];
$this->files_to_scan[$file_path] = $file_path;
unset($this->classes_to_deep_scan[$fq_classlike_name_lc]);
$this->files_to_deep_scan[$file_path] = $file_path;
$this->deep_scanned_classlike_files[$fq_classlike_name_lc] = true;
}
}
}
/**
* @param string $file_path
* @param array<string, string> $filetype_scanners