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

Don't squeal when autoloading classes

This commit is contained in:
Matthew Brown 2016-10-30 01:13:33 -04:00
parent 3c811381aa
commit 722a7fba5c
6 changed files with 51 additions and 22 deletions

View File

@ -13,7 +13,7 @@ use Psalm\Checker\ProjectChecker;
use Psalm\IssueBuffer;
// show all errors
error_reporting(E_ALL & ~E_STRICT & ~E_DEPRECATED & ~E_WARNING);
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('memory_limit', '2048M');
@ -51,10 +51,6 @@ $show_info = isset($options['show-info'])
: true;
$is_diff = isset($options['diff']);
if ($debug) {
error_reporting(E_ALL & ~E_STRICT & ~E_DEPRECATED);
}
// set the cache directory for the file checker
FileChecker::setCacheDir('/var/tmp/php-parser');

View File

@ -82,8 +82,16 @@ class ClassChecker extends ClassLikeChecker
return false;
}
if (class_exists($absolute_class)) {
$old_level = error_reporting();
error_reporting(0);
$class_exists = class_exists($absolute_class);
error_reporting($old_level);
if ($class_exists) {
$old_level = error_reporting();
error_reporting(0);
$reflected_class = new \ReflectionClass($absolute_class);
error_reporting($old_level);
self::$existing_classes_ci[strtolower($absolute_class)] = true;
self::$existing_classes[$reflected_class->getName()] = true;

View File

@ -301,7 +301,10 @@ abstract class ClassLikeChecker implements StatementsSource
$trait_checkers = [];
foreach ($this->class->stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
$method_id = $this->absolute_class . '::' . strtolower($stmt->name);
@ -321,8 +324,8 @@ abstract class ClassLikeChecker implements StatementsSource
MethodChecker::setDeclaringMethodId($class_context->self . '::' . $this->getMappedMethodName(strtolower($stmt->name)), $method_id);
self::$class_methods[$class_context->self][strtolower($stmt->name)] = true;
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\TraitUse) {
}
elseif ($stmt instanceof PhpParser\Node\Stmt\TraitUse) {
$method_map = [];
foreach ($stmt->adaptations as $adaptation) {
if ($adaptation instanceof PhpParser\Node\Stmt\TraitUseAdaptation\Alias) {
@ -437,7 +440,7 @@ abstract class ClassLikeChecker implements StatementsSource
}
}
if (method_exists($this->absolute_class, '__get')) {
if (MethodChecker::methodExists($this->absolute_class . '::__get')) {
$this->has_custom_get = true;
}
@ -763,7 +766,10 @@ abstract class ClassLikeChecker implements StatementsSource
}
try {
$old_level = error_reporting();
error_reporting(0);
$reflected_class = new ReflectionClass($class_name);
error_reporting($old_level);
}
catch (\ReflectionException $e) {
return false;

View File

@ -169,39 +169,40 @@ class FileChecker implements StatementsSource
|| $stmt instanceof PhpParser\Node\Stmt\Namespace_
|| $stmt instanceof PhpParser\Node\Stmt\Function_
) {
if ($leftover_stmts) {
$statments_checker->check($leftover_stmts, $file_context);
$leftover_stmts = [];
}
if ($stmt instanceof PhpParser\Node\Stmt\Class_) {
if ($check_classes) {
$class_checker = ClassLikeChecker::getClassLikeCheckerFromClass($stmt->name) ?: new ClassChecker($stmt, $this, $stmt->name);
$this->declared_classes[] = $class_checker->getAbsoluteClass();
$class_checker->check($check_functions);
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Interface_) {
}
elseif ($stmt instanceof PhpParser\Node\Stmt\Interface_) {
if ($check_classes) {
$class_checker = ClassLikeChecker::getClassLikeCheckerFromClass($stmt->name) ?: new InterfaceChecker($stmt, $this, $stmt->name);
$this->declared_classes[] = $class_checker->getAbsoluteClass();
$class_checker->check(false);
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Trait_) {
}
elseif ($stmt instanceof PhpParser\Node\Stmt\Trait_) {
if ($check_classes) {
$trait_checker = ClassLikeChecker::getClassLikeCheckerFromClass($stmt->name) ?: new TraitChecker($stmt, $this, $stmt->name);
$trait_checker->check($check_functions);
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Namespace_ && $stmt->name instanceof PhpParser\Node\Name) {
}
elseif ($stmt instanceof PhpParser\Node\Stmt\Namespace_ && $stmt->name instanceof PhpParser\Node\Name) {
$namespace_name = implode('\\', $stmt->name->parts);
$namespace_checker = new NamespaceChecker($stmt, $this);
$this->namespace_aliased_classes[$namespace_name] = $namespace_checker->check($check_classes, $check_functions);
$this->declared_classes = array_merge($namespace_checker->getDeclaredClasses());
}
elseif ($stmt instanceof PhpParser\Node\Stmt\Function_ && $check_functions) {
$function_context = new Context($this->short_file_name, $file_context->self);
@ -211,12 +212,15 @@ class FileChecker implements StatementsSource
$function_checkers[$stmt->name]->checkReturnTypes();
}
}
}
else {
$leftover_stmts[] = $stmt;
}
}
if ($leftover_stmts) {
$statments_checker->check($leftover_stmts, $file_context);
}
@ -231,6 +235,8 @@ class FileChecker implements StatementsSource
self::$files_checked[$this->real_file_name] = true;
return $stmts;
}
@ -501,7 +507,10 @@ class FileChecker implements StatementsSource
*/
public static function getClassLikeCheckerFromClass($class_name)
{
$old_level = error_reporting();
error_reporting(0);
$file_name = (string)(new \ReflectionClass($class_name))->getFileName();
error_reporting($old_level);
if (isset(self::$file_checkers[$file_name])) {
$file_checker = self::$file_checkers[$file_name];

View File

@ -59,6 +59,7 @@ class NamespaceChecker implements StatementsSource
$leftover_stmts = [];
foreach ($this->namespace->stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\ClassLike) {
$absolute_class = ClassLikeChecker::getAbsoluteClassFromString($stmt->name, $this->namespace_name, []);
@ -70,34 +71,43 @@ class NamespaceChecker implements StatementsSource
$class_checker = ClassLikeChecker::getClassLikeCheckerFromClass($absolute_class) ?: new ClassChecker($stmt, $this, $absolute_class);
$class_checker->check($check_class_statements);
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Interface_) {
}
elseif ($stmt instanceof PhpParser\Node\Stmt\Interface_) {
if ($check_classes) {
$class_checker = ClassLikeChecker::getClassLikeCheckerFromClass($stmt->name) ?: new InterfaceChecker($stmt, $this, $absolute_class);
$this->declared_classes[] = $class_checker->getAbsoluteClass();
$class_checker->check(false);
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Trait_) {
}
elseif ($stmt instanceof PhpParser\Node\Stmt\Trait_) {
if ($check_classes) {
// register the trait checker
ClassLikeChecker::getClassLikeCheckerFromClass($absolute_class) ?: new TraitChecker($stmt, $this, $absolute_class);
}
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Use_) {
}
elseif ($stmt instanceof PhpParser\Node\Stmt\Use_) {
foreach ($stmt->uses as $use) {
$this->aliased_classes[strtolower($use->alias)] = implode('\\', $use->name->parts);
}
} else {
}
else {
$leftover_stmts[] = $stmt;
}
}
if ($leftover_stmts) {
$statments_checker = new StatementsChecker($this);
$context = new Context($this->file_name);
$statments_checker->check($leftover_stmts, $context);
}
return $this->aliased_classes;
}

View File

@ -1263,7 +1263,7 @@ class ExpressionChecker
if ($absolute_class) {
$stmt->inferredType = new Type\Union([new Type\Atomic($absolute_class)]);
if (method_exists($absolute_class, '__construct')) {
if (MethodChecker::methodExists($absolute_class . '::__construct')) {
$method_id = $absolute_class . '::__construct';
if (self::checkFunctionArguments($statements_checker, $stmt->args, $method_id, $context, $stmt->getLine()) === false) {
@ -2093,7 +2093,7 @@ class ExpressionChecker
// fall through to default
default:
if (method_exists($absolute_class, '__call') || $is_mock || $context->isPhantomClass($absolute_class)) {
if (MethodChecker::methodExists($absolute_class . '::__call') || $is_mock || $context->isPhantomClass($absolute_class)) {
$return_type = Type::getMixed();
continue;
}
@ -2367,7 +2367,7 @@ class ExpressionChecker
$has_mock = $has_mock || $is_mock;
if (is_string($stmt->name) && !method_exists($absolute_class, '__callStatic') && !$is_mock) {
if (is_string($stmt->name) && !MethodChecker::methodExists($absolute_class . '::__callStatic') && !$is_mock) {
$method_id = $absolute_class . '::' . strtolower($stmt->name);
$cased_method_id = $absolute_class . '::' . $stmt->name;