mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
parent
f679900028
commit
4552e69ef2
@ -117,6 +117,10 @@ class NewChecker extends \Psalm\Checker\Statements\Expression\CallChecker
|
||||
foreach ($stmt->class->inferredType->getTypes() as $lhs_type_part) {
|
||||
// this is always OK
|
||||
if ($lhs_type_part instanceof Type\Atomic\TClassString) {
|
||||
if (!isset($stmt->inferredType)) {
|
||||
$stmt->inferredType = Type::parseString($lhs_type_part->class_type);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -124,6 +128,8 @@ class NewChecker extends \Psalm\Checker\Statements\Expression\CallChecker
|
||||
if ($config->allow_string_standin_for_class
|
||||
&& !$lhs_type_part instanceof Type\Atomic\TNumericString
|
||||
) {
|
||||
$stmt->inferredType = Type::getObject();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -137,16 +143,22 @@ class NewChecker extends \Psalm\Checker\Statements\Expression\CallChecker
|
||||
// fall through
|
||||
}
|
||||
|
||||
$stmt->inferredType = Type::getObject();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($lhs_type_part instanceof Type\Atomic\TMixed) {
|
||||
$stmt->inferredType = Type::getObject();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($lhs_type_part instanceof Type\Atomic\TNull
|
||||
&& $stmt->class->inferredType->ignore_nullable_issues
|
||||
) {
|
||||
$stmt->inferredType = Type::getObject();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -160,11 +172,11 @@ class NewChecker extends \Psalm\Checker\Statements\Expression\CallChecker
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
|
||||
$stmt->inferredType = Type::getObject();
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->inferredType = Type::getObject();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ class ConstFetchChecker
|
||||
}
|
||||
|
||||
if ($stmt->name === 'class') {
|
||||
$stmt->inferredType = Type::getClassString();
|
||||
$stmt->inferredType = Type::getClassString($fq_class_name);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -555,11 +555,13 @@ abstract class Type
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class_type
|
||||
*
|
||||
* @return Type\Union
|
||||
*/
|
||||
public static function getClassString()
|
||||
public static function getClassString($class_type = 'object')
|
||||
{
|
||||
$type = new TClassString;
|
||||
$type = new TClassString($class_type);
|
||||
|
||||
return new Union([$type]);
|
||||
}
|
||||
@ -856,6 +858,10 @@ abstract class Type
|
||||
unset($combination->type_params['array']);
|
||||
}
|
||||
|
||||
if ($combination->class_string_types) {
|
||||
$new_types[] = new TClassString(implode('|', $combination->class_string_types));
|
||||
}
|
||||
|
||||
foreach ($combination->type_params as $generic_type => $generic_type_params) {
|
||||
if ($generic_type === 'array') {
|
||||
if ($combination->objectlike_entries) {
|
||||
@ -993,6 +999,14 @@ abstract class Type
|
||||
foreach ($possibly_undefined_entries as $type) {
|
||||
$type->possibly_undefined = true;
|
||||
}
|
||||
} elseif ($type instanceof TClassString) {
|
||||
if (!isset($combination->class_string_types['object'])) {
|
||||
$class_string_types = explode('|', $type->class_type);
|
||||
|
||||
foreach ($class_string_types as $class_string_type) {
|
||||
$combination->class_string_types[strtolower($class_string_type)] = $class_string_type;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$combination->value_types[$type_key] = $type;
|
||||
}
|
||||
|
@ -3,6 +3,18 @@ namespace Psalm\Type\Atomic;
|
||||
|
||||
class TClassString extends TString
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $class_type;
|
||||
|
||||
/**
|
||||
* @param string $class_type string
|
||||
*/
|
||||
public function __construct($class_type = 'object') {
|
||||
$this->class_type = $class_type;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return 'class-string';
|
||||
|
@ -11,4 +11,7 @@ class TypeCombination
|
||||
|
||||
/** @var array<string|int, Union> */
|
||||
public $objectlike_entries = [];
|
||||
|
||||
/** @var array<string, string> */
|
||||
public $class_string_types = [];
|
||||
}
|
||||
|
@ -753,6 +753,16 @@ class TypeReconciliationTest extends TestCase
|
||||
|
||||
function takesNullableString(?string $s) : void {}',
|
||||
],
|
||||
'classStringInstantiation' => [
|
||||
'<?php
|
||||
class Foo {}
|
||||
class Bar {}
|
||||
$class = mt_rand(0, 1) === 1 ? Foo::class : Bar::class;
|
||||
$object = new $class();',
|
||||
'assertions' => [
|
||||
'$object' => 'Foo|Bar',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user