1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Swap in Fully-Qualified for Absolute terms

This commit is contained in:
Matthew Brown 2016-11-07 17:29:51 -05:00
parent 5046caa240
commit 622a0794c3
22 changed files with 334 additions and 334 deletions

View File

@ -80,7 +80,7 @@ class TemplateChecker extends Psalm\Checker\FileChecker
{
$class = explode('::', $method_id)[0];
if (ClassLikeChecker::checkAbsoluteClassOrInterface($class, $this->short_file_name, 1, []) === false) {
if (ClassLikeChecker::checkFullQualifiedClassOrInterface($class, $this->short_file_name, 1, []) === false) {
return false;
}

View File

@ -40,27 +40,27 @@ class ClassChecker extends ClassLikeChecker
/**
* @param PhpParser\Node\Stmt\ClassLike $class
* @param StatementsSource $source
* @param string|null $absolute_class
* @param string|null $fq_class_name
*/
public function __construct(PhpParser\Node\Stmt\ClassLike $class, StatementsSource $source, $absolute_class)
public function __construct(PhpParser\Node\Stmt\ClassLike $class, StatementsSource $source, $fq_class_name)
{
if (!$class instanceof PhpParser\Node\Stmt\Class_) {
throw new \InvalidArgumentException('Bad');
}
if ($absolute_class === null) {
$absolute_class = 'PsalmAnonymousClass' . (self::$anonymous_class_count++);
if ($fq_class_name === null) {
$fq_class_name = 'PsalmAnonymousClass' . (self::$anonymous_class_count++);
}
parent::__construct($class, $source, $absolute_class);
parent::__construct($class, $source, $fq_class_name);
self::$existing_classes[$absolute_class] = true;
self::$existing_classes_ci[strtolower($absolute_class)] = true;
self::$existing_classes[$fq_class_name] = true;
self::$existing_classes_ci[strtolower($fq_class_name)] = true;
self::$class_implements[$absolute_class] = [];
self::$class_implements[$fq_class_name] = [];
if ($this->class->extends) {
$this->parent_class = self::getAbsoluteClassFromName(
$this->parent_class = self::getFullQualifiedClassFromName(
$this->class->extends,
$this->namespace,
$this->aliased_classes
@ -68,51 +68,51 @@ class ClassChecker extends ClassLikeChecker
}
foreach ($class->implements as $interface_name) {
$absolute_interface_name = self::getAbsoluteClassFromName(
$fq_interface_name = self::getFullQualifiedClassFromName(
$interface_name,
$this->namespace,
$this->aliased_classes
);
self::$class_implements[$absolute_class][strtolower($absolute_interface_name)] = $absolute_interface_name;
self::$class_implements[$fq_class_name][strtolower($fq_interface_name)] = $fq_interface_name;
}
}
/**
* Determine whether or not a given class exists
*
* @param string $absolute_class
* @param string $fq_class_name
* @return bool
*/
public static function classExists($absolute_class)
public static function classExists($fq_class_name)
{
if (isset(self::$existing_classes_ci[strtolower($absolute_class)])) {
return self::$existing_classes_ci[strtolower($absolute_class)];
if (isset(self::$existing_classes_ci[strtolower($fq_class_name)])) {
return self::$existing_classes_ci[strtolower($fq_class_name)];
}
if (in_array($absolute_class, self::$SPECIAL_TYPES)) {
if (in_array($fq_class_name, self::$SPECIAL_TYPES)) {
return false;
}
$old_level = error_reporting();
error_reporting(0);
$class_exists = class_exists($absolute_class);
$class_exists = class_exists($fq_class_name);
error_reporting($old_level);
if ($class_exists) {
$old_level = error_reporting();
error_reporting(0);
$reflected_class = new \ReflectionClass($absolute_class);
$reflected_class = new \ReflectionClass($fq_class_name);
error_reporting($old_level);
self::$existing_classes_ci[strtolower($absolute_class)] = true;
self::$existing_classes_ci[strtolower($fq_class_name)] = true;
self::$existing_classes[$reflected_class->getName()] = true;
return true;
}
// we can only be sure that the case-sensitive version does not exist
self::$existing_classes[$absolute_class] = false;
self::$existing_classes[$fq_class_name] = false;
return false;
}
@ -120,90 +120,90 @@ class ClassChecker extends ClassLikeChecker
/**
* Determine whether or not a class has the correct casing
*
* @param string $absolute_class
* @param string $fq_class_name
* @return bool
*/
public static function hasCorrectCasing($absolute_class)
public static function hasCorrectCasing($fq_class_name)
{
if (!self::classExists($absolute_class)) {
throw new \InvalidArgumentException('Cannot check casing on nonexistent class ' . $absolute_class);
if (!self::classExists($fq_class_name)) {
throw new \InvalidArgumentException('Cannot check casing on nonexistent class ' . $fq_class_name);
}
return isset(self::$existing_classes[$absolute_class]);
return isset(self::$existing_classes[$fq_class_name]);
}
/**
* Determine whether or not a class extends a parent
*
* @param string $absolute_class
* @param string $fq_class_name
* @param string $possible_parent
* @return bool
*/
public static function classExtends($absolute_class, $possible_parent)
public static function classExtends($fq_class_name, $possible_parent)
{
if (isset(self::$class_extends[$absolute_class][$possible_parent])) {
return self::$class_extends[$absolute_class][$possible_parent];
if (isset(self::$class_extends[$fq_class_name][$possible_parent])) {
return self::$class_extends[$fq_class_name][$possible_parent];
}
if (!self::classExists($absolute_class) || !self::classExists($possible_parent)) {
if (!self::classExists($fq_class_name) || !self::classExists($possible_parent)) {
return false;
}
if (!isset(self::$class_extends[$absolute_class])) {
self::$class_extends[$absolute_class] = [];
if (!isset(self::$class_extends[$fq_class_name])) {
self::$class_extends[$fq_class_name] = [];
}
self::$class_extends[$absolute_class][$possible_parent] = is_subclass_of($absolute_class, $possible_parent);
self::$class_extends[$fq_class_name][$possible_parent] = is_subclass_of($fq_class_name, $possible_parent);
return self::$class_extends[$absolute_class][$possible_parent];
return self::$class_extends[$fq_class_name][$possible_parent];
}
/**
* Get all the interfaces a given class implements
*
* @param string $absolute_class
* @param string $fq_class_name
* @return array<string>
*/
public static function getInterfacesForClass($absolute_class)
public static function getInterfacesForClass($fq_class_name)
{
if (!isset(self::$class_implements[$absolute_class])) {
if (!isset(self::$class_implements[$fq_class_name])) {
/** @var string[] */
$class_implements = class_implements($absolute_class);
$class_implements = class_implements($fq_class_name);
self::$class_implements[$absolute_class] = [];
self::$class_implements[$fq_class_name] = [];
foreach ($class_implements as $interface) {
self::$class_implements[$absolute_class][strtolower($interface)] = $interface;
self::$class_implements[$fq_class_name][strtolower($interface)] = $interface;
}
}
return self::$class_implements[$absolute_class];
return self::$class_implements[$fq_class_name];
}
/**
* Check whether a class implements an interface
*
* @param string $absolute_class
* @param string $fq_class_name
* @param string $interface
* @return bool
*/
public static function classImplements($absolute_class, $interface)
public static function classImplements($fq_class_name, $interface)
{
$interface_id = strtolower($interface);
if ($interface_id === 'callable' && $absolute_class === 'Closure') {
if ($interface_id === 'callable' && $fq_class_name === 'Closure') {
return true;
}
if (isset(self::$class_implements[$absolute_class][$interface_id])) {
if (isset(self::$class_implements[$fq_class_name][$interface_id])) {
return true;
}
if (isset(self::$class_implements[$absolute_class])) {
if (isset(self::$class_implements[$fq_class_name])) {
return false;
}
if (!ClassChecker::classExists($absolute_class)) {
if (!ClassChecker::classExists($fq_class_name)) {
return false;
}
@ -211,7 +211,7 @@ class ClassChecker extends ClassLikeChecker
return false;
}
$class_implementations = self::getInterfacesForClass($absolute_class);
$class_implementations = self::getInterfacesForClass($fq_class_name);
return isset($class_implementations[$interface_id]);
}

View File

@ -61,7 +61,7 @@ abstract class ClassLikeChecker implements StatementsSource
/**
* @var string
*/
protected $absolute_class;
protected $fq_class_name;
/**
* @var bool
@ -197,24 +197,24 @@ abstract class ClassLikeChecker implements StatementsSource
/**
* @param PhpParser\Node\Stmt\ClassLike $class
* @param StatementsSource $source
* @param string $absolute_class
* @param string $fq_class_name
*/
public function __construct(PhpParser\Node\Stmt\ClassLike $class, StatementsSource $source, $absolute_class)
public function __construct(PhpParser\Node\Stmt\ClassLike $class, StatementsSource $source, $fq_class_name)
{
$this->class = $class;
$this->namespace = $source->getNamespace();
$this->aliased_classes = $source->getAliasedClasses();
$this->file_name = $source->getFileName();
$this->include_file_name = $source->getIncludeFileName();
$this->absolute_class = $absolute_class;
$this->fq_class_name = $fq_class_name;
$this->suppressed_issues = $source->getSuppressedIssues();
self::$class_files[$absolute_class] = $this->file_name;
self::$file_classes[$this->file_name][] = $absolute_class;
self::$class_files[$fq_class_name] = $this->file_name;
self::$file_classes[$this->file_name][] = $fq_class_name;
if (self::$this_class) {
self::$class_checkers[$absolute_class] = $this;
self::$class_checkers[$fq_class_name] = $this;
}
}
@ -227,15 +227,15 @@ abstract class ClassLikeChecker implements StatementsSource
{
if (!$check_methods &&
!($this instanceof TraitChecker) &&
isset(self::$registered_classes[$this->absolute_class])
isset(self::$registered_classes[$this->fq_class_name])
) {
return null;
}
$config = Config::getInstance();
self::$registered_classes[$this->absolute_class] = true;
self::$user_defined[$this->absolute_class] = true;
self::$registered_classes[$this->fq_class_name] = true;
self::$user_defined[$this->fq_class_name] = true;
$leftover_stmts = [];
@ -244,22 +244,22 @@ abstract class ClassLikeChecker implements StatementsSource
$long_file_name = Config::getInstance()->getBaseDir() . $this->file_name;
self::$class_methods[$this->absolute_class] = [];
self::$class_methods[$this->fq_class_name] = [];
self::$public_class_properties[$this->absolute_class] = [];
self::$protected_class_properties[$this->absolute_class] = [];
self::$private_class_properties[$this->absolute_class] = [];
self::$public_class_properties[$this->fq_class_name] = [];
self::$protected_class_properties[$this->fq_class_name] = [];
self::$private_class_properties[$this->fq_class_name] = [];
self::$public_static_class_properties[$this->absolute_class] = [];
self::$protected_static_class_properties[$this->absolute_class] = [];
self::$private_static_class_properties[$this->absolute_class] = [];
self::$public_static_class_properties[$this->fq_class_name] = [];
self::$protected_static_class_properties[$this->fq_class_name] = [];
self::$private_static_class_properties[$this->fq_class_name] = [];
self::$public_class_constants[$this->absolute_class] = [];
self::$public_class_constants[$this->fq_class_name] = [];
if (!$class_context) {
$class_context = new Context($this->file_name, $this->absolute_class);
$class_context = new Context($this->file_name, $this->fq_class_name);
$class_context->parent = $this->parent_class;
$class_context->vars_in_scope['$this'] = new Type\Union([new Type\Atomic($this->absolute_class)]);
$class_context->vars_in_scope['$this'] = new Type\Union([new Type\Atomic($this->fq_class_name)]);
}
// set all constants first
@ -278,8 +278,8 @@ abstract class ClassLikeChecker implements StatementsSource
$extra_interfaces = [];
foreach (self::$class_implements[$this->absolute_class] as $interface_id => $interface_name) {
if (self::checkAbsoluteClassOrInterface(
foreach (self::$class_implements[$this->fq_class_name] as $interface_id => $interface_name) {
if (self::checkFullQualifiedClassOrInterface(
$interface_name,
$this->file_name,
$this->class->getLine(),
@ -301,7 +301,7 @@ abstract class ClassLikeChecker implements StatementsSource
foreach ($extra_interfaces as $extra_interface_name) {
FileChecker::addFileInheritanceToClass($long_file_name, $extra_interface_name);
self::$class_implements[$this->absolute_class][strtolower($extra_interface_name)] =
self::$class_implements[$this->fq_class_name][strtolower($extra_interface_name)] =
$extra_interface_name;
}
}
@ -332,7 +332,7 @@ abstract class ClassLikeChecker implements StatementsSource
}
}
if (MethodChecker::methodExists($this->absolute_class . '::__get')) {
if (MethodChecker::methodExists($this->fq_class_name . '::__get')) {
$this->has_custom_get = true;
}
@ -341,9 +341,9 @@ abstract class ClassLikeChecker implements StatementsSource
}
$all_instance_properties = array_merge(
self::$public_class_properties[$this->absolute_class],
self::$protected_class_properties[$this->absolute_class],
self::$private_class_properties[$this->absolute_class]
self::$public_class_properties[$this->fq_class_name],
self::$protected_class_properties[$this->fq_class_name],
self::$private_class_properties[$this->fq_class_name]
);
foreach ($all_instance_properties as $property_name => $property_type) {
@ -351,34 +351,34 @@ abstract class ClassLikeChecker implements StatementsSource
}
$all_static_properties = array_merge(
self::$public_static_class_properties[$this->absolute_class],
self::$protected_static_class_properties[$this->absolute_class],
self::$private_static_class_properties[$this->absolute_class]
self::$public_static_class_properties[$this->fq_class_name],
self::$protected_static_class_properties[$this->fq_class_name],
self::$private_static_class_properties[$this->fq_class_name]
);
foreach ($all_static_properties as $property_name => $property_type) {
$class_context->vars_in_scope[$this->absolute_class . '::$' . $property_name] = $property_type
$class_context->vars_in_scope[$this->fq_class_name . '::$' . $property_name] = $property_type
?: Type::getMixed();
}
$config = Config::getInstance();
if ($this instanceof ClassChecker) {
foreach (ClassChecker::getInterfacesForClass($this->absolute_class) as $interface_id => $interface_name) {
foreach (ClassChecker::getInterfacesForClass($this->fq_class_name) as $interface_id => $interface_name) {
if (isset(self::$public_class_constants[$interface_name])) {
self::$public_class_constants[$this->absolute_class] +=
self::$public_class_constants[$this->fq_class_name] +=
self::$public_class_constants[$interface_name];
}
foreach (self::$class_methods[$interface_name] as $method_name => $_) {
$mentioned_method_id = $interface_name . '::' . $method_name;
$implemented_method_id = $this->absolute_class . '::' . $method_name;
$implemented_method_id = $this->fq_class_name . '::' . $method_name;
MethodChecker::setOverriddenMethodId($implemented_method_id, $mentioned_method_id);
if (!isset(self::$class_methods[$this->absolute_class])) {
if (!isset(self::$class_methods[$this->fq_class_name])) {
if (IssueBuffer::accepts(
new UnimplementedInterfaceMethod(
'Method ' . $method_name . ' is not defined on class ' . $this->absolute_class,
'Method ' . $method_name . ' is not defined on class ' . $this->fq_class_name,
$this->file_name,
$this->class->getLine()
),
@ -409,7 +409,7 @@ abstract class ClassLikeChecker implements StatementsSource
}
if (!$this->class->name) {
$this->class->name = $this->absolute_class;
$this->class->name = $this->fq_class_name;
}
return null;
@ -421,7 +421,7 @@ abstract class ClassLikeChecker implements StatementsSource
*/
protected function registerParentClassProperties($parent_class)
{
if (self::checkAbsoluteClassOrInterface(
if (self::checkFullQualifiedClassOrInterface(
$parent_class,
$this->file_name,
$this->class->getLine(),
@ -437,20 +437,20 @@ abstract class ClassLikeChecker implements StatementsSource
FileChecker::addFileInheritanceToClass(Config::getInstance()->getBaseDir() . $this->file_name, $parent_class);
self::$class_implements[$this->absolute_class] += self::$class_implements[$parent_class];
self::$class_implements[$this->fq_class_name] += self::$class_implements[$parent_class];
self::$public_class_properties[$this->absolute_class] = self::$public_class_properties[$parent_class];
self::$protected_class_properties[$this->absolute_class] = self::$protected_class_properties[$parent_class];
self::$public_class_properties[$this->fq_class_name] = self::$public_class_properties[$parent_class];
self::$protected_class_properties[$this->fq_class_name] = self::$protected_class_properties[$parent_class];
self::$public_static_class_properties[$this->absolute_class] =
self::$public_static_class_properties[$this->fq_class_name] =
self::$public_static_class_properties[$parent_class];
self::$protected_static_class_properties[$this->absolute_class] =
self::$protected_static_class_properties[$this->fq_class_name] =
self::$protected_static_class_properties[$parent_class];
self::$public_class_constants[$this->absolute_class] = array_merge(
self::$public_class_constants[$this->fq_class_name] = array_merge(
self::$public_class_constants[$parent_class],
self::$public_class_constants[$this->absolute_class]
self::$public_class_constants[$this->fq_class_name]
);
return null;
@ -469,7 +469,7 @@ abstract class ClassLikeChecker implements StatementsSource
array &$method_checkers,
$cache_method_checker
) {
$method_id = $this->absolute_class . '::' . strtolower($stmt->name);
$method_id = $this->fq_class_name . '::' . strtolower($stmt->name);
if (!isset(self::$method_checkers[$method_id])) {
$method_checker = new MethodChecker($stmt, $this);
@ -514,7 +514,7 @@ abstract class ClassLikeChecker implements StatementsSource
}
foreach ($stmt->traits as $trait) {
$trait_name = self::getAbsoluteClassFromName(
$trait_name = self::getFullQualifiedClassFromName(
$trait,
$this->namespace,
$this->aliased_classes
@ -585,7 +585,7 @@ abstract class ClassLikeChecker implements StatementsSource
} elseif (!$comment && $check_property_types) {
if (IssueBuffer::accepts(
new MissingPropertyType(
'Property ' . $this->absolute_class . '::$' . $stmt->props[0]->name . ' does not have a ' .
'Property ' . $this->fq_class_name . '::$' . $stmt->props[0]->name . ' does not have a ' .
'declared type',
$this->file_name,
$stmt->getLine()
@ -681,7 +681,7 @@ abstract class ClassLikeChecker implements StatementsSource
foreach ($class_checker->class->stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
if ($declaring_method_id === $class_checker->absolute_class . '::' . strtolower($stmt->name)) {
if ($declaring_method_id === $class_checker->fq_class_name . '::' . strtolower($stmt->name)) {
$method_checker = new MethodChecker($stmt, $class_checker);
self::$method_checkers[$method_id] = $method_checker;
return $method_checker;
@ -710,51 +710,51 @@ abstract class ClassLikeChecker implements StatementsSource
/**
* Check whether a class/interface exists
*
* @param string $absolute_class
* @param string $fq_class_name
* @return bool
*/
public static function classOrInterfaceExists($absolute_class)
public static function classOrInterfaceExists($fq_class_name)
{
return ClassChecker::classExists($absolute_class) || InterfaceChecker::interfaceExists($absolute_class);
return ClassChecker::classExists($fq_class_name) || InterfaceChecker::interfaceExists($fq_class_name);
}
/**
* @param string $absolute_class
* @param string $fq_class_name
* @param string $possible_parent
* @return bool
*/
public static function classExtendsOrImplements($absolute_class, $possible_parent)
public static function classExtendsOrImplements($fq_class_name, $possible_parent)
{
return ClassChecker::classExtends($absolute_class, $possible_parent)
|| ClassChecker::classImplements($absolute_class, $possible_parent);
return ClassChecker::classExtends($fq_class_name, $possible_parent)
|| ClassChecker::classImplements($fq_class_name, $possible_parent);
}
/**
* @param string $absolute_class
* @param string $fq_class_name
* @param string $file_name
* @param int $line_number
* @param array<string> $suppressed_issues
* @return bool|null
*/
public static function checkAbsoluteClassOrInterface(
$absolute_class,
public static function checkFullQualifiedClassOrInterface(
$fq_class_name,
$file_name,
$line_number,
array $suppressed_issues
) {
if (empty($absolute_class)) {
if (empty($fq_class_name)) {
throw new \InvalidArgumentException('$class cannot be empty');
}
$absolute_class = preg_replace('/^\\\/', '', $absolute_class);
$fq_class_name = preg_replace('/^\\\/', '', $fq_class_name);
$class_exists = ClassChecker::classExists($absolute_class);
$interface_exists = InterfaceChecker::interfaceExists($absolute_class);
$class_exists = ClassChecker::classExists($fq_class_name);
$interface_exists = InterfaceChecker::interfaceExists($fq_class_name);
if (!$class_exists && !$interface_exists) {
if (IssueBuffer::accepts(
new UndefinedClass(
'Class or interface ' . $absolute_class . ' does not exist',
'Class or interface ' . $fq_class_name . ' does not exist',
$file_name,
$line_number
),
@ -766,12 +766,12 @@ abstract class ClassLikeChecker implements StatementsSource
return null;
}
if (($class_exists && !ClassChecker::hasCorrectCasing($absolute_class))
|| ($interface_exists && !InterfaceChecker::hasCorrectCasing($absolute_class))
if (($class_exists && !ClassChecker::hasCorrectCasing($fq_class_name))
|| ($interface_exists && !InterfaceChecker::hasCorrectCasing($fq_class_name))
) {
if (IssueBuffer::accepts(
new InvalidClass(
'Class or interface ' . $absolute_class . ' has wrong casing',
'Class or interface ' . $fq_class_name . ' has wrong casing',
$file_name,
$line_number
),
@ -781,7 +781,7 @@ abstract class ClassLikeChecker implements StatementsSource
}
}
FileChecker::addFileReferenceToClass(Config::getInstance()->getBaseDir() . $file_name, $absolute_class);
FileChecker::addFileReferenceToClass(Config::getInstance()->getBaseDir() . $file_name, $fq_class_name);
return true;
}
@ -794,7 +794,7 @@ abstract class ClassLikeChecker implements StatementsSource
* @param array<int,string> $aliased_classes
* @return string
*/
public static function getAbsoluteClassFromName(
public static function getFullQualifiedClassFromName(
PhpParser\Node\Name $class_name,
$namespace,
array $aliased_classes
@ -803,7 +803,7 @@ abstract class ClassLikeChecker implements StatementsSource
return implode('\\', $class_name->parts);
}
return self::getAbsoluteClassFromString(implode('\\', $class_name->parts), $namespace, $aliased_classes);
return self::getFullQualifiedClassFromString(implode('\\', $class_name->parts), $namespace, $aliased_classes);
}
/**
@ -812,7 +812,7 @@ abstract class ClassLikeChecker implements StatementsSource
* @param array<string, string> $imported_namespaces
* @return string
*/
public static function getAbsoluteClassFromString($class, $namespace, array $imported_namespaces)
public static function getFullQualifiedClassFromString($class, $namespace, array $imported_namespaces)
{
if (empty($class)) {
throw new \InvalidArgumentException('$class cannot be empty');
@ -855,9 +855,9 @@ abstract class ClassLikeChecker implements StatementsSource
/**
* @return string
*/
public function getAbsoluteClass()
public function getFullQualifiedClass()
{
return $this->absolute_class;
return $this->fq_class_name;
}
/**
@ -1138,11 +1138,11 @@ abstract class ClassLikeChecker implements StatementsSource
$parent_method_id = $parent_class . '::' . $method_name;
/** @var string */
$declaring_method_id = MethodChecker::getDeclaringMethodId($parent_method_id);
$implemented_method_id = $this->absolute_class . '::' . $method_name;
$implemented_method_id = $this->fq_class_name . '::' . $method_name;
if (!isset(self::$class_methods[$this->absolute_class][$method_name])) {
if (!isset(self::$class_methods[$this->fq_class_name][$method_name])) {
MethodChecker::setDeclaringMethodId($implemented_method_id, $declaring_method_id);
self::$class_methods[$this->absolute_class][$method_name] = true;
self::$class_methods[$this->fq_class_name][$method_name] = true;
MethodChecker::setOverriddenMethodId($implemented_method_id, $declaring_method_id);
}
}
@ -1302,13 +1302,13 @@ abstract class ClassLikeChecker implements StatementsSource
}
/**
* @param string $absolute_class
* @param string $fq_class_name
* @return boolean
*/
public static function isUserDefined($absolute_class)
public static function isUserDefined($fq_class_name)
{
self::registerClass($absolute_class);
return isset(self::$user_defined[$absolute_class]);
self::registerClass($fq_class_name);
return isset(self::$user_defined[$fq_class_name]);
}
/**

View File

@ -41,7 +41,7 @@ class CommentChecker
if ($line_parts && $line_parts[0]) {
$type_in_comments = FunctionLikeChecker::fixUpLocalType(
$line_parts[0],
$source->getAbsoluteClass(),
$source->getFullQualifiedClass(),
$source->getNamespace(),
$source->getAliasedClasses()
);

View File

@ -194,7 +194,7 @@ class FileChecker implements StatementsSource
$class_checker = ClassLikeChecker::getClassLikeCheckerFromClass($stmt->name)
?: new ClassChecker($stmt, $this, $stmt->name);
$this->declared_classes[] = $class_checker->getAbsoluteClass();
$this->declared_classes[] = $class_checker->getFullQualifiedClass();
$class_checker->check($check_functions);
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Interface_) {
@ -202,7 +202,7 @@ class FileChecker implements StatementsSource
$class_checker = ClassLikeChecker::getClassLikeCheckerFromClass($stmt->name)
?: new InterfaceChecker($stmt, $this, $stmt->name);
$this->declared_classes[] = $class_checker->getAbsoluteClass();
$this->declared_classes[] = $class_checker->getFullQualifiedClass();
$class_checker->check(false);
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Trait_) {
@ -260,7 +260,7 @@ class FileChecker implements StatementsSource
* @param string $file_name
* @return string
*/
public static function getAbsoluteClassFromNameInFile($class, $namespace, $file_name)
public static function getFullQualifiedClassFromNameInFile($class, $namespace, $file_name)
{
if (isset(self::$file_checkers[$file_name])) {
$aliased_classes = self::$file_checkers[$file_name]->getAliasedClasses($namespace);
@ -270,7 +270,7 @@ class FileChecker implements StatementsSource
$aliased_classes = $file_checker->getAliasedClasses($namespace);
}
return ClassLikeChecker::getAbsoluteClassFromString($class, $namespace, $aliased_classes);
return ClassLikeChecker::getFullQualifiedClassFromString($class, $namespace, $aliased_classes);
}
/**
@ -440,7 +440,7 @@ class FileChecker implements StatementsSource
/**
* @return null
*/
public function getAbsoluteClass()
public function getFullQualifiedClass()
{
return null;
}
@ -583,23 +583,23 @@ class FileChecker implements StatementsSource
/**
* @param string $source_file
* @param string $absolute_class
* @param string $fq_class_name
* @return void
*/
public static function addFileReferenceToClass($source_file, $absolute_class)
public static function addFileReferenceToClass($source_file, $fq_class_name)
{
self::$referencing_files[$source_file] = true;
self::$file_references_to_class[$absolute_class][$source_file] = true;
self::$file_references_to_class[$fq_class_name][$source_file] = true;
}
/**
* @param string $source_file
* @param string $absolute_class
* @param string $fq_class_name
* @return void
*/
public static function addFileInheritanceToClass($source_file, $absolute_class)
public static function addFileInheritanceToClass($source_file, $fq_class_name)
{
self::$files_inheriting_classes[$absolute_class][$source_file] = true;
self::$files_inheriting_classes[$fq_class_name][$source_file] = true;
}
/**

View File

@ -194,7 +194,7 @@ class FunctionChecker extends FunctionLikeChecker
foreach ($function->getParams() as $param) {
$param_array = self::getTranslatedParam(
$param,
$this->absolute_class,
$this->fq_class_name,
$this->namespace,
$this->getAliasedClasses()
);
@ -239,7 +239,7 @@ class FunctionChecker extends FunctionLikeChecker
$return_type = Type::parseString(
is_string($function->returnType)
? $function->returnType
: ClassLikeChecker::getAbsoluteClassFromName(
: ClassLikeChecker::getFullQualifiedClassFromName(
$function->returnType,
$this->namespace,
$this->getAliasedClasses()

View File

@ -48,7 +48,7 @@ abstract class FunctionLikeChecker implements StatementsSource
/**
* @var string
*/
protected $absolute_class;
protected $fq_class_name;
/**
* @var StatementsChecker|null
@ -102,7 +102,7 @@ abstract class FunctionLikeChecker implements StatementsSource
$this->class_extends = $source->getParentClass();
$this->file_name = $source->getFileName();
$this->include_file_name = $source->getIncludeFileName();
$this->absolute_class = $source->getAbsoluteClass();
$this->fq_class_name = $source->getFullQualifiedClass();
$this->source = $source;
$this->suppressed_issues = $source->getSuppressedIssues();
}
@ -218,7 +218,7 @@ abstract class FunctionLikeChecker implements StatementsSource
foreach ($this->function->getParams() as $param) {
$function_params[] = self::getTranslatedParam(
$param,
$this->absolute_class,
$this->fq_class_name,
$this->namespace,
$this->getAliasedClasses()
);
@ -237,7 +237,7 @@ abstract class FunctionLikeChecker implements StatementsSource
if ($atomic_type->isObjectType()
&& !$atomic_type->isObject()
&& $this->function instanceof PhpParser\Node
&& ClassLikeChecker::checkAbsoluteClassOrInterface(
&& ClassLikeChecker::checkFullQualifiedClassOrInterface(
$atomic_type->value,
$this->file_name,
$this->function->getLine(),
@ -327,7 +327,7 @@ abstract class FunctionLikeChecker implements StatementsSource
{
if ($this->function instanceof Function_ || $this->function instanceof ClassMethod) {
return ($this instanceof MethodChecker
? $this->absolute_class . '::'
? $this->fq_class_name . '::'
: '') . strtolower($this->function->name);
}
@ -353,9 +353,9 @@ abstract class FunctionLikeChecker implements StatementsSource
/**
* @return string
*/
public function getAbsoluteClass()
public function getFullQualifiedClass()
{
return $this->absolute_class;
return $this->fq_class_name;
}
/**
@ -488,7 +488,7 @@ abstract class FunctionLikeChecker implements StatementsSource
$declared_return_type = ExpressionChecker::fleshOutTypes(
$method_return_types,
[],
$this->absolute_class,
$this->fq_class_name,
$method_id
);
@ -560,7 +560,7 @@ abstract class FunctionLikeChecker implements StatementsSource
if (!TypeChecker::hasIdenticalTypes(
$declared_return_type,
$inferred_return_type,
$this->absolute_class
$this->fq_class_name
)) {
if (IssueBuffer::accepts(
new InvalidReturnType(
@ -659,14 +659,14 @@ abstract class FunctionLikeChecker implements StatementsSource
/**
* @param PhpParser\Node\Param $param
* @param string $absolute_class
* @param string $fq_class_name
* @param string $namespace
* @param array<string> $aliased_classes
* @return FunctionLikeParameter
*/
public static function getTranslatedParam(
PhpParser\Node\Param $param,
$absolute_class,
$fq_class_name,
$namespace,
array $aliased_classes
) {
@ -683,9 +683,9 @@ abstract class FunctionLikeChecker implements StatementsSource
} elseif ($param->type instanceof PhpParser\Node\Name\FullyQualified) {
$param_type_string = implode('\\', $param->type->parts);
} elseif ($param->type->parts === ['self']) {
$param_type_string = $absolute_class;
$param_type_string = $fq_class_name;
} else {
$param_type_string = ClassLikeChecker::getAbsoluteClassFromString(
$param_type_string = ClassLikeChecker::getFullQualifiedClassFromString(
implode('\\', $param->type->parts),
$namespace,
$aliased_classes
@ -778,12 +778,12 @@ abstract class FunctionLikeChecker implements StatementsSource
/**
* @param string $return_type
* @param string|null $absolute_class
* @param string|null $fq_class_name
* @param string $namespace
* @param array $aliased_classes
* @return string
*/
public static function fixUpLocalType($return_type, $absolute_class, $namespace, array $aliased_classes)
public static function fixUpLocalType($return_type, $fq_class_name, $namespace, array $aliased_classes)
{
if (strpos($return_type, '[') !== false) {
$return_type = Type::convertSquareBrackets($return_type);
@ -816,7 +816,7 @@ abstract class FunctionLikeChecker implements StatementsSource
continue;
}
$return_type_token = ClassLikeChecker::getAbsoluteClassFromString(
$return_type_token = ClassLikeChecker::getFullQualifiedClassFromString(
$return_type_token,
$namespace,
$aliased_classes
@ -947,15 +947,15 @@ abstract class FunctionLikeChecker implements StatementsSource
*/
public static function getParamsById($method_id, array $args, $file_name)
{
$absolute_class = strpos($method_id, '::') !== false ? explode('::', $method_id)[0] : null;
$fq_class_name = strpos($method_id, '::') !== false ? explode('::', $method_id)[0] : null;
if ($absolute_class && ClassLikeChecker::isUserDefined($absolute_class)) {
if ($fq_class_name && ClassLikeChecker::isUserDefined($fq_class_name)) {
/** @var array<\Psalm\FunctionLikeParameter> */
return MethodChecker::getMethodParams($method_id);
} elseif (!$absolute_class && FunctionChecker::inCallMap($method_id)) {
} elseif (!$fq_class_name && FunctionChecker::inCallMap($method_id)) {
/** @var array<array<FunctionLikeParameter>> */
$function_param_options = FunctionChecker::getParamsFromCallMap($method_id);
} elseif ($absolute_class) {
} elseif ($fq_class_name) {
if ($method_params = MethodChecker::getMethodParams($method_id)) {
// fall back to using reflected params anyway
return $method_params;

View File

@ -41,7 +41,7 @@ class InterfaceChecker extends ClassLikeChecker
self::$parent_interfaces[$interface_name] = [];
foreach ($interface->extends as $extended_interface) {
$extended_interface_name = self::getAbsoluteClassFromName(
$extended_interface_name = self::getFullQualifiedClassFromName(
$extended_interface,
$this->namespace,
$this->aliased_classes

View File

@ -255,8 +255,8 @@ class MethodChecker extends FunctionLikeChecker
*/
protected function registerMethod(PhpParser\Node\Stmt\ClassMethod $method)
{
$method_id = $this->absolute_class . '::' . strtolower($method->name);
$cased_method_id = self::$cased_method_ids[$method_id] = $this->absolute_class . '::' . $method->name;
$method_id = $this->fq_class_name . '::' . strtolower($method->name);
$cased_method_id = self::$cased_method_ids[$method_id] = $this->fq_class_name . '::' . $method->name;
if (isset(self::$have_reflected[$method_id]) || isset(self::$have_registered[$method_id])) {
$this->suppressed_issues = self::$method_suppress[$method_id];
@ -287,7 +287,7 @@ class MethodChecker extends FunctionLikeChecker
foreach ($method->getParams() as $param) {
$param_array = $this->getTranslatedParam(
$param,
$this->absolute_class,
$this->fq_class_name,
$this->namespace,
$this->getAliasedClasses()
);
@ -307,7 +307,7 @@ class MethodChecker extends FunctionLikeChecker
$return_type = Type::parseString(
is_string($method->returnType)
? $method->returnType
: ClassLikeChecker::getAbsoluteClassFromName(
: ClassLikeChecker::getFullQualifiedClassFromName(
$method->returnType,
$this->namespace,
$this->getAliasedClasses()
@ -349,7 +349,7 @@ class MethodChecker extends FunctionLikeChecker
$return_type = Type::parseString(
$this->fixUpLocalType(
(string)$docblock_info['return_type'],
$this->absolute_class,
$this->fq_class_name,
$this->namespace,
$this->getAliasedClasses()
)
@ -402,14 +402,14 @@ class MethodChecker extends FunctionLikeChecker
$return_type_token = Type::fixScalarTerms($return_type_token);
if ($return_type_token[0] === strtoupper($return_type_token[0])) {
$absolute_class = explode('::', $method_id)[0];
$fq_class_name = explode('::', $method_id)[0];
if ($return_type_token === '$this') {
$return_type_token = $absolute_class;
$return_type_token = $fq_class_name;
continue;
}
$return_type_token = FileChecker::getAbsoluteClassFromNameInFile(
$return_type_token = FileChecker::getFullQualifiedClassFromNameInFile(
$return_type_token,
self::$method_namespaces[$method_id],
self::$method_files[$method_id]
@ -541,7 +541,7 @@ class MethodChecker extends FunctionLikeChecker
}
}
if ($source->getSource() instanceof TraitChecker && $method_class === $source->getAbsoluteClass()) {
if ($source->getSource() instanceof TraitChecker && $method_class === $source->getFullQualifiedClass()) {
return null;
}

View File

@ -67,29 +67,29 @@ class NamespaceChecker implements StatementsSource
foreach ($this->namespace->stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\ClassLike) {
$absolute_class = ClassLikeChecker::getAbsoluteClassFromString($stmt->name, $this->namespace_name, []);
$fq_class_name = ClassLikeChecker::getFullQualifiedClassFromString($stmt->name, $this->namespace_name, []);
if ($stmt instanceof PhpParser\Node\Stmt\Class_) {
$this->declared_classes[$absolute_class] = 1;
$this->declared_classes[$fq_class_name] = 1;
if ($check_classes) {
$class_checker = ClassLikeChecker::getClassLikeCheckerFromClass($absolute_class)
?: new ClassChecker($stmt, $this, $absolute_class);
$class_checker = ClassLikeChecker::getClassLikeCheckerFromClass($fq_class_name)
?: new ClassChecker($stmt, $this, $fq_class_name);
$class_checker->check($check_class_statements);
}
} 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();
?: new InterfaceChecker($stmt, $this, $fq_class_name);
$this->declared_classes[] = $class_checker->getFullQualifiedClass();
$class_checker->check(false);
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Trait_) {
if ($check_classes) {
// register the trait checker
ClassLikeChecker::getClassLikeCheckerFromClass($absolute_class)
?: new TraitChecker($stmt, $this, $absolute_class);
ClassLikeChecker::getClassLikeCheckerFromClass($fq_class_name)
?: new TraitChecker($stmt, $this, $fq_class_name);
}
}
} elseif ($stmt instanceof PhpParser\Node\Stmt\Use_) {
@ -148,7 +148,7 @@ class NamespaceChecker implements StatementsSource
/**
* @return null
*/
public function getAbsoluteClass()
public function getFullQualifiedClass()
{
return null;
}

View File

@ -42,7 +42,7 @@ class ForeachChecker
$var_id = ExpressionChecker::getVarId(
$stmt->expr,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -157,7 +157,7 @@ class ForeachChecker
if ($return_type->value !== 'Traversable' &&
$return_type->value !== $statements_checker->getClassName()
) {
if (ClassLikeChecker::checkAbsoluteClassOrInterface(
if (ClassLikeChecker::checkFullQualifiedClassOrInterface(
$return_type->value,
$statements_checker->getCheckedFileName(),
$stmt->getLine(),

View File

@ -75,21 +75,21 @@ class IfChecker
if ($stmt->cond instanceof PhpParser\Node\Expr\BinaryOp) {
$reconcilable_if_types = TypeChecker::getReconcilableTypeAssertions(
$stmt->cond,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
$negatable_if_types = TypeChecker::getNegatableTypeAssertions(
$stmt->cond,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
} else {
$reconcilable_if_types = $negatable_if_types = TypeChecker::getTypeAssertions(
$stmt->cond,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -258,21 +258,21 @@ class IfChecker
if ($elseif->cond instanceof PhpParser\Node\Expr\BinaryOp) {
$reconcilable_elseif_types = TypeChecker::getReconcilableTypeAssertions(
$elseif->cond,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
$negatable_elseif_types = TypeChecker::getNegatableTypeAssertions(
$elseif->cond,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
} else {
$reconcilable_elseif_types = $negatable_elseif_types = TypeChecker::getTypeAssertions(
$elseif->cond,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);

View File

@ -32,17 +32,17 @@ class TryChecker
foreach ($stmt->catches as $catch) {
$catch_context = clone $original_context;
$catch_class = ClassLikeChecker::getAbsoluteClassFromName(
$catch_class = ClassLikeChecker::getFullQualifiedClassFromName(
$catch->type,
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
if ($context->check_classes) {
$absolute_class = $catch_class;
$fq_class_name = $catch_class;
if (ClassLikeChecker::checkAbsoluteClassOrInterface(
$absolute_class,
if (ClassLikeChecker::checkFullQualifiedClassOrInterface(
$fq_class_name,
$statements_checker->getCheckedFileName(),
$stmt->getLine(),
$statements_checker->getSuppressedIssues()

View File

@ -29,7 +29,7 @@ class WhileChecker
$while_types = TypeChecker::getTypeAssertions(
$stmt->cond,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);

View File

@ -46,14 +46,14 @@ class AssignmentChecker
) {
$var_id = ExpressionChecker::getVarId(
$assign_var,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
$array_var_id = ExpressionChecker::getArrayVarId(
$assign_var,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -113,7 +113,7 @@ class AssignmentChecker
$list_var_id = ExpressionChecker::getVarId(
$var,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -248,7 +248,7 @@ class AssignmentChecker
$var_id = ExpressionChecker::getVarId(
$stmt,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -515,30 +515,30 @@ class AssignmentChecker
$var_id = ExpressionChecker::getVarId(
$stmt,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
$absolute_class = (string)$stmt->class->inferredType;
$fq_class_name = (string)$stmt->class->inferredType;
if (($stmt->class instanceof PhpParser\Node\Name && $stmt->class->parts[0] === 'this') ||
$absolute_class === $context->self
$fq_class_name === $context->self
) {
$class_visibility = \ReflectionProperty::IS_PRIVATE;
} elseif ($context->self && ClassChecker::classExtends($absolute_class, $context->self)) {
} elseif ($context->self && ClassChecker::classExtends($fq_class_name, $context->self)) {
$class_visibility = \ReflectionProperty::IS_PROTECTED;
} else {
$class_visibility = \ReflectionProperty::IS_PUBLIC;
}
$class_properties = ClassLikeChecker::getStaticPropertiesForClass(
$absolute_class,
$fq_class_name,
$class_visibility
);
$all_class_properties = ClassLikeChecker::getStaticPropertiesForClass(
$absolute_class,
$fq_class_name,
$class_visibility
);
@ -549,7 +549,7 @@ class AssignmentChecker
if ($class_visibility !== \ReflectionProperty::IS_PRIVATE) {
$all_class_properties = ClassLikeChecker::getStaticPropertiesForClass(
$absolute_class,
$fq_class_name,
\ReflectionProperty::IS_PRIVATE
);
}
@ -601,7 +601,7 @@ class AssignmentChecker
if ($class_property_type === false) {
if (IssueBuffer::accepts(
new MissingPropertyType(
'Property ' . $absolute_class . '::$' . $prop_name . ' does not have a declared type',
'Property ' . $fq_class_name . '::$' . $prop_name . ' does not have a declared type',
$statements_checker->getCheckedFileName(),
$stmt->getLine()
),
@ -623,7 +623,7 @@ class AssignmentChecker
return null;
}
$class_property_type = ExpressionChecker::fleshOutTypes($class_property_type, [], $absolute_class);
$class_property_type = ExpressionChecker::fleshOutTypes($class_property_type, [], $fq_class_name);
if (!$assignment_type->isIn($class_property_type)) {
if (IssueBuffer::accepts(
@ -682,7 +682,7 @@ class AssignmentChecker
$nesting = 0;
$var_id = ExpressionChecker::getVarId(
$stmt->var,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses(),
$nesting
@ -711,7 +711,7 @@ class AssignmentChecker
$array_var_id = ExpressionChecker::getArrayVarId(
$stmt->var,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);

View File

@ -98,7 +98,7 @@ class CallChecker
$method_id = implode('', $stmt->name->parts);
if ($context->self) {
//$method_id = $statements_checker->getAbsoluteClass() . '::' . $method_id;
//$method_id = $statements_checker->getFullQualifiedClass() . '::' . $method_id;
}
$in_call_map = FunctionChecker::inCallMap($method_id);
@ -162,23 +162,23 @@ class CallChecker
PhpParser\Node\Expr\New_ $stmt,
Context $context
) {
$absolute_class = null;
$fq_class_name = null;
if ($stmt->class instanceof PhpParser\Node\Name) {
if (!in_array($stmt->class->parts[0], ['self', 'static', 'parent'])) {
if ($context->check_classes) {
$absolute_class = ClassLikeChecker::getAbsoluteClassFromName(
$fq_class_name = ClassLikeChecker::getFullQualifiedClassFromName(
$stmt->class,
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
if ($context->isPhantomClass($absolute_class)) {
if ($context->isPhantomClass($fq_class_name)) {
return null;
}
if (ClassLikeChecker::checkAbsoluteClassOrInterface(
$absolute_class,
if (ClassLikeChecker::checkFullQualifiedClassOrInterface(
$fq_class_name,
$statements_checker->getCheckedFileName(),
$stmt->getLine(),
$statements_checker->getSuppressedIssues()
@ -189,31 +189,31 @@ class CallChecker
} else {
switch ($stmt->class->parts[0]) {
case 'self':
$absolute_class = $context->self;
$fq_class_name = $context->self;
break;
case 'parent':
$absolute_class = $context->parent;
$fq_class_name = $context->parent;
break;
case 'static':
// @todo maybe we can do better here
$absolute_class = $context->self;
$fq_class_name = $context->self;
break;
}
}
} elseif ($stmt->class instanceof PhpParser\Node\Stmt\Class_) {
$statements_checker->check([$stmt->class], $context);
$absolute_class = $stmt->class->name;
$fq_class_name = $stmt->class->name;
} else {
ExpressionChecker::check($statements_checker, $stmt->class, $context);
}
if ($absolute_class) {
$stmt->inferredType = new Type\Union([new Type\Atomic($absolute_class)]);
if ($fq_class_name) {
$stmt->inferredType = new Type\Union([new Type\Atomic($fq_class_name)]);
if (MethodChecker::methodExists($absolute_class . '::__construct')) {
$method_id = $absolute_class . '::__construct';
if (MethodChecker::methodExists($fq_class_name . '::__construct')) {
$method_id = $fq_class_name . '::__construct';
if (self::checkFunctionArguments(
$statements_checker,
@ -225,7 +225,7 @@ class CallChecker
return false;
}
if ($absolute_class === 'ArrayIterator' && isset($stmt->args[0]->value->inferredType)) {
if ($fq_class_name === 'ArrayIterator' && isset($stmt->args[0]->value->inferredType)) {
/** @var Type\Union */
$first_arg_type = $stmt->args[0]->value->inferredType;
@ -257,7 +257,7 @@ class CallChecker
$stmt->inferredType = new Type\Union([
new Type\Generic(
$absolute_class,
$fq_class_name,
[
$key_type,
$value_type
@ -311,7 +311,7 @@ class CallChecker
$var_id = ExpressionChecker::getVarId(
$stmt->var,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -336,12 +336,12 @@ class CallChecker
if (($this_class = ClassLikeChecker::getThisClass()) &&
(
$this_class === $statements_checker->getAbsoluteClass() ||
ClassChecker::classExtends($this_class, $statements_checker->getAbsoluteClass()) ||
TraitChecker::traitExists($statements_checker->getAbsoluteClass())
$this_class === $statements_checker->getFullQualifiedClass() ||
ClassChecker::classExtends($this_class, $statements_checker->getFullQualifiedClass()) ||
TraitChecker::traitExists($statements_checker->getFullQualifiedClass())
)
) {
$method_id = $statements_checker->getAbsoluteClass() . '::' . strtolower($stmt->name);
$method_id = $statements_checker->getFullQualifiedClass() . '::' . strtolower($stmt->name);
if ($statements_checker->checkInsideMethod($method_id, $context) === false) {
return false;
@ -360,13 +360,13 @@ class CallChecker
$return_type = null;
foreach ($class_type->types as $type) {
$absolute_class = $type->value;
$fq_class_name = $type->value;
$is_mock = ExpressionChecker::isMock($absolute_class);
$is_mock = ExpressionChecker::isMock($fq_class_name);
$has_mock = $has_mock || $is_mock;
switch ($absolute_class) {
switch ($fq_class_name) {
case 'null':
if (IssueBuffer::accepts(
new NullReference(
@ -412,20 +412,20 @@ class CallChecker
break;
case 'static':
$absolute_class = (string) $context->self;
$fq_class_name = (string) $context->self;
// fall through to default
default:
if (MethodChecker::methodExists($absolute_class . '::__call') ||
if (MethodChecker::methodExists($fq_class_name . '::__call') ||
$is_mock ||
$context->isPhantomClass($absolute_class)
$context->isPhantomClass($fq_class_name)
) {
$return_type = Type::getMixed();
continue;
}
$does_class_exist = ClassLikeChecker::checkAbsoluteClassOrInterface(
$absolute_class,
$does_class_exist = ClassLikeChecker::checkFullQualifiedClassOrInterface(
$fq_class_name,
$statements_checker->getCheckedFileName(),
$stmt->getLine(),
$statements_checker->getSuppressedIssues()
@ -435,8 +435,8 @@ class CallChecker
return $does_class_exist;
}
$method_id = $absolute_class . '::' . strtolower($stmt->name);
$cased_method_id = $absolute_class . '::' . $stmt->name;
$method_id = $fq_class_name . '::' . strtolower($stmt->name);
$cased_method_id = $fq_class_name . '::' . $stmt->name;
$does_method_exist = MethodChecker::checkMethodExists(
$cased_method_id,
@ -478,7 +478,7 @@ class CallChecker
$return_type_candidate = ExpressionChecker::fleshOutTypes(
$return_type_candidate,
$stmt->args,
$absolute_class,
$fq_class_name,
$method_id
);
@ -530,18 +530,18 @@ class CallChecker
}
$method_id = null;
$absolute_class = null;
$fq_class_name = null;
$lhs_type = null;
if ($stmt->class instanceof PhpParser\Node\Name) {
$absolute_class = null;
$fq_class_name = null;
if (count($stmt->class->parts) === 1 && in_array($stmt->class->parts[0], ['self', 'static', 'parent'])) {
if ($stmt->class->parts[0] === 'parent') {
$absolute_class = $statements_checker->getParentClass();
$fq_class_name = $statements_checker->getParentClass();
if ($absolute_class === null) {
if ($fq_class_name === null) {
if (IssueBuffer::accepts(
new ParentNotFound(
'Cannot call method on parent as this class does not extend another',
@ -560,25 +560,25 @@ class CallChecker
? $statements_checker->getNamespace() . '\\'
: '';
$absolute_class = $namespace . $statements_checker->getClassName();
$fq_class_name = $namespace . $statements_checker->getClassName();
}
if ($context->isPhantomClass($absolute_class)) {
if ($context->isPhantomClass($fq_class_name)) {
return null;
}
} elseif ($context->check_classes) {
$absolute_class = ClassLikeChecker::getAbsoluteClassFromName(
$fq_class_name = ClassLikeChecker::getFullQualifiedClassFromName(
$stmt->class,
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
if ($context->isPhantomClass($absolute_class)) {
if ($context->isPhantomClass($fq_class_name)) {
return null;
}
$does_class_exist = ClassLikeChecker::checkAbsoluteClassOrInterface(
$absolute_class,
$does_class_exist = ClassLikeChecker::checkFullQualifiedClassOrInterface(
$fq_class_name,
$statements_checker->getCheckedFileName(),
$stmt->getLine(),
$statements_checker->getSuppressedIssues()
@ -591,7 +591,7 @@ class CallChecker
if ($stmt->class->parts === ['parent'] && is_string($stmt->name)) {
if (ClassLikeChecker::getThisClass()) {
$method_id = $absolute_class . '::' . strtolower($stmt->name);
$method_id = $fq_class_name . '::' . strtolower($stmt->name);
if ($statements_checker->checkInsideMethod($method_id, $context) === false) {
return false;
@ -599,8 +599,8 @@ class CallChecker
}
}
if ($absolute_class) {
$lhs_type = new Type\Union([new Type\Atomic($absolute_class)]);
if ($fq_class_name) {
$lhs_type = new Type\Union([new Type\Atomic($fq_class_name)]);
}
} else {
ExpressionChecker::check($statements_checker, $stmt->class, $context);
@ -616,18 +616,18 @@ class CallChecker
$has_mock = false;
foreach ($lhs_type->types as $lhs_type_part) {
$absolute_class = $lhs_type_part->value;
$fq_class_name = $lhs_type_part->value;
$is_mock = ExpressionChecker::isMock($absolute_class);
$is_mock = ExpressionChecker::isMock($fq_class_name);
$has_mock = $has_mock || $is_mock;
if (is_string($stmt->name) &&
!MethodChecker::methodExists($absolute_class . '::__callStatic') &&
!MethodChecker::methodExists($fq_class_name . '::__callStatic') &&
!$is_mock
) {
$method_id = $absolute_class . '::' . strtolower($stmt->name);
$cased_method_id = $absolute_class . '::' . $stmt->name;
$method_id = $fq_class_name . '::' . strtolower($stmt->name);
$cased_method_id = $fq_class_name . '::' . $stmt->name;
$does_method_exist = MethodChecker::checkMethodExists(
$cased_method_id,
@ -653,7 +653,7 @@ class CallChecker
if ($stmt->class instanceof PhpParser\Node\Name
&& $stmt->class->parts[0] !== 'parent'
&& $context->self
&& ($statements_checker->isStatic() || !ClassChecker::classExtends($context->self, $absolute_class))
&& ($statements_checker->isStatic() || !ClassChecker::classExtends($context->self, $fq_class_name))
) {
if (MethodChecker::checkMethodStatic(
$method_id,
@ -681,8 +681,8 @@ class CallChecker
$return_types,
$stmt->args,
$stmt->class instanceof PhpParser\Node\Name && $stmt->class->parts === ['parent']
? $statements_checker->getAbsoluteClass()
: $absolute_class,
? $statements_checker->getFullQualifiedClass()
: $fq_class_name,
$method_id
);
@ -730,7 +730,7 @@ class CallChecker
$is_variadic = false;
$absolute_class = null;
$fq_class_name = null;
$in_call_map = $method_id ? FunctionChecker::inCallMap($method_id) : false;
@ -744,7 +744,7 @@ class CallChecker
if ($in_call_map || !strpos($method_id, '::')) {
$is_variadic = FunctionChecker::isVariadic(strtolower($method_id), $statements_checker->getFileName());
} else {
$absolute_class = explode('::', $method_id)[0];
$fq_class_name = explode('::', $method_id)[0];
$is_variadic = $is_mock || MethodChecker::isVariadic($method_id);
}
}
@ -774,7 +774,7 @@ class CallChecker
} else {
$var_id = ExpressionChecker::getVarId(
$arg->value,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -868,7 +868,7 @@ class CallChecker
ExpressionChecker::fleshOutTypes(
clone $param_type,
[],
$absolute_class,
$fq_class_name,
$method_id
),
$cased_method_id,
@ -948,7 +948,7 @@ class CallChecker
$translated_param = FunctionLikeChecker::getTranslatedParam(
$closure_param,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);

View File

@ -57,14 +57,14 @@ class FetchChecker
$stmt_var_id = ExpressionChecker::getVarId(
$stmt->var,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
$var_id = ExpressionChecker::getVarId(
$stmt,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -162,7 +162,7 @@ class FetchChecker
if (!$lhs_type_part->isObjectType()) {
$stmt_var_id = ExpressionChecker::getVarId(
$stmt->var,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -230,7 +230,7 @@ class FetchChecker
|| $lhs_type_part->value === $context->self
|| (
$statements_checker->getSource()->getSource() instanceof TraitChecker &&
$lhs_type_part->value === $statements_checker->getSource()->getAbsoluteClass()
$lhs_type_part->value === $statements_checker->getSource()->getFullQualifiedClass()
)
) {
$class_visibility = \ReflectionProperty::IS_PRIVATE;
@ -372,16 +372,16 @@ class FetchChecker
$stmt->class->parts !== ['static']
) {
if ($stmt->class->parts === ['self']) {
$absolute_class = (string)$context->self;
$fq_class_name = (string)$context->self;
} else {
$absolute_class = ClassLikeChecker::getAbsoluteClassFromName(
$fq_class_name = ClassLikeChecker::getFullQualifiedClassFromName(
$stmt->class,
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
if (ClassLikeChecker::checkAbsoluteClassOrInterface(
$absolute_class,
if (ClassLikeChecker::checkFullQualifiedClassOrInterface(
$fq_class_name,
$statements_checker->getCheckedFileName(),
$stmt->getLine(),
$statements_checker->getSuppressedIssues()
@ -390,14 +390,14 @@ class FetchChecker
}
}
$const_id = $absolute_class . '::' . $stmt->name;
$const_id = $fq_class_name . '::' . $stmt->name;
if ($stmt->name === 'class') {
$stmt->inferredType = Type::getString();
return null;
}
$class_constants = ClassLikeChecker::getConstantsForClass($absolute_class, \ReflectionProperty::IS_PUBLIC);
$class_constants = ClassLikeChecker::getConstantsForClass($fq_class_name, \ReflectionProperty::IS_PUBLIC);
if (!isset($class_constants[$stmt->name])) {
if (IssueBuffer::accepts(
@ -445,14 +445,14 @@ class FetchChecker
}
$method_id = null;
$absolute_class = null;
$fq_class_name = null;
if ($stmt->class instanceof PhpParser\Node\Name) {
if (count($stmt->class->parts) === 1 && in_array($stmt->class->parts[0], ['self', 'static', 'parent'])) {
if ($stmt->class->parts[0] === 'parent') {
$absolute_class = $statements_checker->getParentClass();
$fq_class_name = $statements_checker->getParentClass();
if ($absolute_class === null) {
if ($fq_class_name === null) {
if (IssueBuffer::accepts(
new ParentNotFound(
'Cannot check property fetch on parent as this class does not extend another',
@ -467,27 +467,27 @@ class FetchChecker
return;
}
} else {
$absolute_class = ($statements_checker->getNamespace()
$fq_class_name = ($statements_checker->getNamespace()
? $statements_checker->getNamespace() . '\\'
: '') . $statements_checker->getClassName();
}
if ($context->isPhantomClass($absolute_class)) {
if ($context->isPhantomClass($fq_class_name)) {
return null;
}
} elseif ($context->check_classes) {
$absolute_class = ClassLikeChecker::getAbsoluteClassFromName(
$fq_class_name = ClassLikeChecker::getFullQualifiedClassFromName(
$stmt->class,
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
if ($context->isPhantomClass($absolute_class)) {
if ($context->isPhantomClass($fq_class_name)) {
return null;
}
if (ClassLikeChecker::checkAbsoluteClassOrInterface(
$absolute_class,
if (ClassLikeChecker::checkFullQualifiedClassOrInterface(
$fq_class_name,
$statements_checker->getCheckedFileName(),
$stmt->getLine(),
$statements_checker->getSuppressedIssues()
@ -496,17 +496,17 @@ class FetchChecker
}
}
$stmt->class->inferredType = $absolute_class ? new Type\Union([new Type\Atomic($absolute_class)]) : null;
$stmt->class->inferredType = $fq_class_name ? new Type\Union([new Type\Atomic($fq_class_name)]) : null;
}
if ($absolute_class &&
if ($fq_class_name &&
$context->check_variables &&
is_string($stmt->name) &&
!ExpressionChecker::isMock($absolute_class)
!ExpressionChecker::isMock($fq_class_name)
) {
$var_id = ExpressionChecker::getVarId(
$stmt,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -517,30 +517,30 @@ class FetchChecker
return null;
}
if ($absolute_class === $context->self
if ($fq_class_name === $context->self
|| (
$statements_checker->getSource()->getSource() instanceof TraitChecker &&
$absolute_class === $statements_checker->getSource()->getAbsoluteClass()
$fq_class_name === $statements_checker->getSource()->getFullQualifiedClass()
)
) {
$class_visibility = \ReflectionProperty::IS_PRIVATE;
} elseif ($context->self && ClassChecker::classExtends($context->self, $absolute_class)) {
} elseif ($context->self && ClassChecker::classExtends($context->self, $fq_class_name)) {
$class_visibility = \ReflectionProperty::IS_PROTECTED;
} else {
$class_visibility = \ReflectionProperty::IS_PUBLIC;
}
$visible_class_properties = ClassLikeChecker::getStaticPropertiesForClass(
$absolute_class,
$fq_class_name,
$class_visibility
);
if (!isset($visible_class_properties[$stmt->name])) {
$all_class_properties = [];
if ($absolute_class !== $context->self) {
if ($fq_class_name !== $context->self) {
$all_class_properties = ClassLikeChecker::getStaticPropertiesForClass(
$absolute_class,
$fq_class_name,
\ReflectionProperty::IS_PRIVATE
);
}
@ -604,7 +604,7 @@ class FetchChecker
$nesting = 0;
$var_id = ExpressionChecker::getVarId(
$stmt->var,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses(),
$nesting
@ -617,7 +617,7 @@ class FetchChecker
$array_var_id = ExpressionChecker::getArrayVarId(
$stmt->var,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);

View File

@ -192,7 +192,7 @@ class ExpressionChecker
if (!$statements_checker->isStatic()) {
$this_class = ClassLikeChecker::getThisClass();
$this_class = $this_class &&
ClassChecker::classExtends($this_class, $statements_checker->getAbsoluteClass())
ClassChecker::classExtends($this_class, $statements_checker->getFullQualifiedClass())
? $this_class
: $context->self;
@ -301,14 +301,14 @@ class ExpressionChecker
!in_array($stmt->class->parts[0], ['self', 'static', 'parent'])
) {
if ($context->check_classes) {
$absolute_class = ClassLikeChecker::getAbsoluteClassFromName(
$fq_class_name = ClassLikeChecker::getFullQualifiedClassFromName(
$stmt->class,
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
if (ClassLikeChecker::checkAbsoluteClassOrInterface(
$absolute_class,
if (ClassLikeChecker::checkFullQualifiedClassOrInterface(
$fq_class_name,
$statements_checker->getCheckedFileName(),
$stmt->getLine(),
$statements_checker->getSuppressedIssues()
@ -519,7 +519,7 @@ class ExpressionChecker
) {
$var_id = self::getVarId(
$stmt,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -633,7 +633,7 @@ class ExpressionChecker
} elseif ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd) {
$left_type_assertions = TypeChecker::getReconcilableTypeAssertions(
$stmt->left,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -679,7 +679,7 @@ class ExpressionChecker
} elseif ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr) {
$left_type_assertions = TypeChecker::getNegatableTypeAssertions(
$stmt->left,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -809,16 +809,16 @@ class ExpressionChecker
&& $stmt->class instanceof PhpParser\Node\Name
) {
if (count($stmt->class->parts) === 1 && in_array($stmt->class->parts[0], ['self', 'static', 'parent'])) {
$absolute_class = $this_class_name;
$fq_class_name = $this_class_name;
} else {
$absolute_class = ClassLikeChecker::getAbsoluteClassFromName(
$fq_class_name = ClassLikeChecker::getFullQualifiedClassFromName(
$stmt->class,
$namespace,
$aliased_classes
);
}
return $absolute_class . '::$' . $stmt->name;
return $fq_class_name . '::$' . $stmt->name;
}
if ($stmt instanceof PhpParser\Node\Expr\PropertyFetch && is_string($stmt->name)) {
@ -1079,21 +1079,21 @@ class ExpressionChecker
if ($stmt->cond instanceof PhpParser\Node\Expr\BinaryOp) {
$reconcilable_if_types = TypeChecker::getReconcilableTypeAssertions(
$stmt->cond,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
$negatable_if_types = TypeChecker::getNegatableTypeAssertions(
$stmt->cond,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
} else {
$reconcilable_if_types = $negatable_if_types = TypeChecker::getTypeAssertions(
$stmt->cond,
$statements_checker->getAbsoluteClass(),
$statements_checker->getFullQualifiedClass(),
$statements_checker->getNamespace(),
$statements_checker->getAliasedClasses()
);
@ -1231,12 +1231,12 @@ class ExpressionChecker
}
/**
* @param string $absolute_class
* @param string $fq_class_name
* @return boolean
*/
public static function isMock($absolute_class)
public static function isMock($fq_class_name)
{
return in_array($absolute_class, Config::getInstance()->getMockClasses());
return in_array($fq_class_name, Config::getInstance()->getMockClasses());
}
/**

View File

@ -75,7 +75,7 @@ class StatementsChecker
/**
* @var string
*/
protected $absolute_class;
protected $fq_class_name;
/**
* @var TypeChecker
@ -105,7 +105,7 @@ class StatementsChecker
$this->aliased_classes = $this->source->getAliasedClasses();
$this->namespace = $this->source->getNamespace();
$this->is_static = $this->source->isStatic();
$this->absolute_class = $this->source->getAbsoluteClass();
$this->fq_class_name = $this->source->getFullQualifiedClass();
$this->class_name = $this->source->getClassName();
$this->parent_class = $this->source->getParentClass();
$this->suppressed_issues = $this->source->getSuppressedIssues();
@ -181,7 +181,7 @@ class StatementsChecker
foreach ($stmt->vars as $var) {
$var_id = ExpressionChecker::getArrayVarId(
$var,
$this->absolute_class,
$this->fq_class_name,
$this->namespace,
$this->aliased_classes
);
@ -288,7 +288,7 @@ class StatementsChecker
if (isset($const->value->inferredType) && !$const->value->inferredType->isMixed()) {
ClassLikeChecker::setConstantType(
$this->absolute_class,
$this->fq_class_name,
$const->name,
$const->value->inferredType
);
@ -463,11 +463,11 @@ class StatementsChecker
*/
protected static function getMethodFromCallBlock($call, array $args, $method_id)
{
$absolute_class = explode('::', $method_id)[0];
$fq_class_name = explode('::', $method_id)[0];
$original_call = $call;
$call = preg_replace('/^\$this(->|::)/', $absolute_class . '::', $call);
$call = preg_replace('/^\$this(->|::)/', $fq_class_name . '::', $call);
$call = preg_replace('/\(\)$/', '', $call);
@ -857,9 +857,9 @@ class StatementsChecker
/**
* @return string
*/
public function getAbsoluteClass()
public function getFullQualifiedClass()
{
return $this->absolute_class;
return $this->fq_class_name;
}
/**

View File

@ -15,9 +15,9 @@ class TraitChecker extends ClassLikeChecker
/**
* @param PhpParser\Node\Stmt\ClassLike $class
* @param StatementsSource $source
* @param string $absolute_class
* @param string $fq_class_name
*/
public function __construct(PhpParser\Node\Stmt\ClassLike $class, StatementsSource $source, $absolute_class)
public function __construct(PhpParser\Node\Stmt\ClassLike $class, StatementsSource $source, $fq_class_name)
{
if (!$class instanceof PhpParser\Node\Stmt\Trait_) {
throw new \InvalidArgumentException('Trait checker must be passed a trait');
@ -27,13 +27,13 @@ class TraitChecker extends ClassLikeChecker
$this->namespace = $source->getNamespace();
$this->aliased_classes = $source->getAliasedClasses();
$this->file_name = $source->getFileName();
$this->absolute_class = $absolute_class;
$this->fq_class_name = $fq_class_name;
$this->parent_class = null;
$this->suppressed_issues = $source->getSuppressedIssues();
self::$class_checkers[$absolute_class] = $this;
self::$class_checkers[$fq_class_name] = $this;
}
/**

View File

@ -832,7 +832,7 @@ class TypeChecker
) {
if ($stmt->class instanceof PhpParser\Node\Name) {
if (!in_array($stmt->class->parts[0], ['self', 'static', 'parent'])) {
$instanceof_class = ClassLikeChecker::getAbsoluteClassFromName(
$instanceof_class = ClassLikeChecker::getFullQualifiedClassFromName(
$stmt->class,
$namespace,
$aliased_classes
@ -1565,10 +1565,10 @@ class TypeChecker
/**
* @param Type\Union $declared_type
* @param Type\Union $inferred_type
* @param string $absolute_class
* @param string $fq_class_name
* @return boolean
*/
public static function hasIdenticalTypes(Type\Union $declared_type, Type\Union $inferred_type, $absolute_class)
public static function hasIdenticalTypes(Type\Union $declared_type, Type\Union $inferred_type, $fq_class_name)
{
if ($declared_type->isMixed() || $inferred_type->isEmpty()) {
return true;
@ -1578,7 +1578,7 @@ class TypeChecker
return false;
}
$inferred_type = ExpressionChecker::fleshOutTypes($inferred_type, [], $absolute_class, '');
$inferred_type = ExpressionChecker::fleshOutTypes($inferred_type, [], $fq_class_name, '');
$simple_declared_types = array_filter(
array_keys($declared_type->types),
@ -1651,7 +1651,7 @@ class TypeChecker
if (!self::hasIdenticalTypes(
$declared_atomic_type->type_params[$offset],
$inferred_atomic_type->type_params[$offset],
$absolute_class
$fq_class_name
)) {
return false;
}
@ -1682,7 +1682,7 @@ class TypeChecker
if (!self::hasIdenticalTypes(
$type_param,
$inferred_atomic_type->properties[$property_name],
$absolute_class
$fq_class_name
)) {
return false;
}

View File

@ -16,7 +16,7 @@ interface StatementsSource
/**
* @return string
*/
public function getAbsoluteClass();
public function getFullQualifiedClass();
/**
* @return string