1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix #1859 - allow function_exists introspection when function exists

This commit is contained in:
Brown 2019-06-28 10:48:30 -04:00
parent 6514f2084c
commit 5943f6036e
3 changed files with 41 additions and 17 deletions

View File

@ -150,8 +150,12 @@ class StatementsAnalyzer extends SourceAnalyzer implements StatementsSource
// hoist functions to the top
foreach ($stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\Function_) {
$function_analyzer = new FunctionAnalyzer($stmt, $this->source);
$this->function_analyzers[strtolower($stmt->name->name)] = $function_analyzer;
try {
$function_analyzer = new FunctionAnalyzer($stmt, $this->source);
$this->function_analyzers[strtolower($stmt->name->name)] = $function_analyzer;
} catch (\UnexpectedValueException $e) {
// do nothing
}
}
}
@ -542,25 +546,28 @@ class StatementsAnalyzer extends SourceAnalyzer implements StatementsSource
$config = Config::getInstance();
$function_context->collect_references = $codebase->collect_references;
$function_context->collect_exceptions = $config->check_for_throws_docblock;
$this->function_analyzers[$function_id]->analyze($function_context, $context);
if ($config->reportIssueInFile('InvalidReturnType', $this->getFilePath())) {
$method_id = $this->function_analyzers[$function_id]->getMethodId();
if (isset($this->function_analyzers[$function_id])) {
$this->function_analyzers[$function_id]->analyze($function_context, $context);
$function_storage = $codebase->functions->getStorage(
$this,
$method_id
);
if ($config->reportIssueInFile('InvalidReturnType', $this->getFilePath())) {
$method_id = $this->function_analyzers[$function_id]->getMethodId();
$return_type = $function_storage->return_type;
$return_type_location = $function_storage->return_type_location;
$function_storage = $codebase->functions->getStorage(
$this,
$method_id
);
$this->function_analyzers[$function_id]->verifyReturnType(
$this,
$return_type,
$this->getFQCLN(),
$return_type_location
);
$return_type = $function_storage->return_type;
$return_type_location = $function_storage->return_type_location;
$this->function_analyzers[$function_id]->verifyReturnType(
$this,
$return_type,
$this->getFQCLN(),
$return_type_location
);
}
}
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Expression) {

View File

@ -611,6 +611,15 @@ class ClassStringTest extends TestCase
new \RuntimeException();
}'
],
'noCrashWhenClassExistsNegated' => [
'<?php
class A {}
if (!class_exists(A::class)) {
new \RuntimeException();
}'
],
];
}

View File

@ -1760,6 +1760,14 @@ class FunctionCallTest extends TestCase
$f->bar();
}'
],
'functionExists' => [
'<?php
if (!function_exists("in_array")) {
function in_array($a, $b) {
return true;
}
}'
],
];
}