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

Allow gettype vars to be compared to strings

This commit is contained in:
Matthew Brown 2019-01-05 16:23:18 -05:00
parent 9e2dacc9e4
commit c7723df8ff
5 changed files with 38 additions and 21 deletions

View File

@ -29,10 +29,7 @@ abstract class ClassLikeAnalyzer extends SourceAnalyzer implements StatementsSou
const VISIBILITY_PROTECTED = 2;
const VISIBILITY_PRIVATE = 3;
/**
* @var array
*/
public static $SPECIAL_TYPES = [
public const SPECIAL_TYPES = [
'int' => 'int',
'string' => 'string',
'float' => 'float',
@ -47,10 +44,7 @@ abstract class ClassLikeAnalyzer extends SourceAnalyzer implements StatementsSou
'mixed' => 'mixed',
];
/**
* @var array
*/
public static $GETTYPE_TYPES = [
public const GETTYPE_TYPES = [
'boolean' => true,
'integer' => true,
'double' => true,

View File

@ -632,7 +632,7 @@ class AssertionFinder
/** @var PhpParser\Node\Scalar\String_ $string_expr */
$var_type = $string_expr->value;
if (!isset(ClassLikeAnalyzer::$GETTYPE_TYPES[$var_type])
if (!isset(ClassLikeAnalyzer::GETTYPE_TYPES[$var_type])
&& $source instanceof StatementsSource
) {
if (IssueBuffer::accepts(
@ -1159,7 +1159,7 @@ class AssertionFinder
throw new \UnexpectedValueException('Shouldnt get here');
}
if (!isset(ClassLikeAnalyzer::$GETTYPE_TYPES[$var_type])) {
if (!isset(ClassLikeAnalyzer::GETTYPE_TYPES[$var_type])) {
if (IssueBuffer::accepts(
new UnevaluatedCode(
'gettype cannot return this value',

View File

@ -18,6 +18,7 @@ use Psalm\Type\Atomic\TGenericIterable;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TGenericParam;
use Psalm\Type\Atomic\GetClassT;
use Psalm\Type\Atomic\GetTypeT;
use Psalm\Type\Atomic\THtmlEscapedString;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIterable;
@ -543,6 +544,22 @@ class TypeAnalyzer
);
}
if ($input_type_part instanceof GetTypeT) {
$input_type_part = new TString();
if ($container_type_part instanceof TLiteralString) {
return isset(ClassLikeAnalyzer::GETTYPE_TYPES[$container_type_part->value]);
}
}
if ($container_type_part instanceof GetTypeT) {
$container_type_part = new TString();
if ($input_type_part instanceof TLiteralString) {
return isset(ClassLikeAnalyzer::GETTYPE_TYPES[$input_type_part->value]);
}
}
if ($input_type_part->shallowEquals($container_type_part)) {
return self::isMatchingTypeContainedBy(
$codebase,
@ -869,16 +886,11 @@ class TypeAnalyzer
if (($input_type_part instanceof TClassString
|| $input_type_part instanceof TLiteralClassString)
&& (get_class($container_type_part) === TString::class
|| get_class($container_type_part) === TSingleLetter::class
|| get_class($container_type_part) === GetClassT::class)
|| get_class($container_type_part) === TSingleLetter::class)
) {
return true;
}
if ($container_type_part instanceof TClassString && $input_type_part instanceof GetClassT) {
return true;
}
if ($container_type_part instanceof TString
&& ($input_type_part instanceof TNumericString
|| $input_type_part instanceof THtmlEscapedString)

View File

@ -393,7 +393,7 @@ class ClassLikes
*/
public function classExists($fq_class_name)
{
if (isset(ClassLikeAnalyzer::$SPECIAL_TYPES[$fq_class_name])) {
if (isset(ClassLikeAnalyzer::SPECIAL_TYPES[$fq_class_name])) {
return false;
}
@ -453,8 +453,8 @@ class ClassLikes
return true;
}
if (isset(ClassLikeAnalyzer::$SPECIAL_TYPES[$interface_id])
|| isset(ClassLikeAnalyzer::$SPECIAL_TYPES[$fq_class_name])
if (isset(ClassLikeAnalyzer::SPECIAL_TYPES[$interface_id])
|| isset(ClassLikeAnalyzer::SPECIAL_TYPES[$fq_class_name])
) {
return false;
}
@ -475,7 +475,7 @@ class ClassLikes
*/
public function interfaceExists($fq_interface_name)
{
if (isset(ClassLikeAnalyzer::$SPECIAL_TYPES[strtolower($fq_interface_name)])) {
if (isset(ClassLikeAnalyzer::SPECIAL_TYPES[strtolower($fq_interface_name)])) {
return false;
}

View File

@ -1268,7 +1268,7 @@ class FunctionCallTest extends TestCase
foo($a);
}',
],
'SKIPPED-getTypeHasValues' => [
'getTypeHasValues' => [
'<?php
/**
* @param mixed $maybe
@ -1649,6 +1649,17 @@ class FunctionCallTest extends TestCase
}',
'error_message' => 'DocblockTypeContradiction',
],
'getTypeInvalidValue' => [
'<?php
/**
* @param mixed $maybe
*/
function matchesTypes($maybe) : void {
$t = gettype($maybe);
if ($t === "bool") {}
}',
'error_message' => 'TypeDoesNotContainType',
],
];
}
}