mirror of
https://github.com/danog/psalm.git
synced 2024-11-29 20:28:59 +01:00
Fix int-mask-of expansion
This commit is contained in:
parent
b58782ae29
commit
e3a352d287
@ -290,8 +290,12 @@ class NonDivArithmeticOpAnalyzer
|
||||
): ?Type\Union {
|
||||
if ($left_type_part instanceof TLiteralInt
|
||||
&& $right_type_part instanceof TLiteralInt
|
||||
&& ($left instanceof PhpParser\Node\Scalar || $left instanceof PhpParser\Node\Expr\ConstFetch)
|
||||
&& ($right instanceof PhpParser\Node\Scalar || $right instanceof PhpParser\Node\Expr\ConstFetch)
|
||||
&& ($left instanceof PhpParser\Node\Scalar
|
||||
|| $left instanceof PhpParser\Node\Expr\ConstFetch
|
||||
|| $left instanceof PhpParser\Node\Expr\ClassConstFetch)
|
||||
&& ($right instanceof PhpParser\Node\Scalar
|
||||
|| $right instanceof PhpParser\Node\Expr\ConstFetch
|
||||
|| $right instanceof PhpParser\Node\Expr\ClassConstFetch)
|
||||
) {
|
||||
// time for some arithmetic!
|
||||
|
||||
|
@ -272,6 +272,12 @@ class ScalarTypeComparator
|
||||
return true;
|
||||
}
|
||||
|
||||
if (get_class($container_type_part) === TInt::class
|
||||
&& $input_type_part instanceof TInt
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((get_class($input_type_part) === TInt::class && $container_type_part instanceof TLiteralInt)
|
||||
|| (get_class($input_type_part) === TPositiveInt::class
|
||||
&& $container_type_part instanceof TLiteralInt
|
||||
|
@ -379,7 +379,46 @@ class TypeExpander
|
||||
$final
|
||||
);
|
||||
|
||||
if (\is_array($new_value_type) || !$new_value_type instanceof Type\Atomic\TLiteralInt) {
|
||||
if (\is_array($new_value_type)) {
|
||||
$new_value_type = reset($new_value_type);
|
||||
}
|
||||
|
||||
if (!$new_value_type instanceof Type\Atomic\TLiteralInt) {
|
||||
return new Type\Atomic\TInt();
|
||||
}
|
||||
|
||||
$potential_ints[] = $new_value_type->value;
|
||||
}
|
||||
|
||||
return \Psalm\Internal\Type\TypeParser::getComputedIntsFromMask($potential_ints);
|
||||
}
|
||||
|
||||
if ($return_type instanceof Type\Atomic\TIntMaskOf) {
|
||||
if (!$evaluate_class_constants) {
|
||||
return new Type\Atomic\TInt();
|
||||
}
|
||||
|
||||
$value_type = $return_type->value;
|
||||
|
||||
$new_value_types = self::expandAtomic(
|
||||
$codebase,
|
||||
$value_type,
|
||||
$self_class,
|
||||
$static_class_type,
|
||||
$parent_class,
|
||||
$evaluate_class_constants,
|
||||
$evaluate_conditional_types,
|
||||
$final
|
||||
);
|
||||
|
||||
if (!is_array($new_value_types)) {
|
||||
return new Type\Atomic\TInt();
|
||||
}
|
||||
|
||||
$potential_ints = [];
|
||||
|
||||
foreach ($new_value_types as $new_value_type) {
|
||||
if (!$new_value_type instanceof Type\Atomic\TLiteralInt) {
|
||||
return new Type\Atomic\TInt();
|
||||
}
|
||||
|
||||
|
@ -1143,6 +1143,40 @@ class AnnotationTest extends TestCase
|
||||
/** @var DateTime $obj */
|
||||
echo $obj->format("Y");'
|
||||
],
|
||||
'intMaskWithClassConstants' => [
|
||||
'<?php
|
||||
class FileFlag {
|
||||
public const OPEN = 1;
|
||||
public const MODIFIED = 2;
|
||||
public const NEW = 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int-mask<FileFlag::OPEN, FileFlag::MODIFIED, FileFlag::NEW> $flags
|
||||
*/
|
||||
function takesFlags(int $flags) : void {
|
||||
echo $flags;
|
||||
}
|
||||
|
||||
takesFlags(FileFlag::MODIFIED | FileFlag::NEW);'
|
||||
],
|
||||
'intMaskOfWithClassWildcard' => [
|
||||
'<?php
|
||||
class FileFlag {
|
||||
public const OPEN = 1;
|
||||
public const MODIFIED = 2;
|
||||
public const NEW = 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int-mask-of<FileFlag::*> $flags
|
||||
*/
|
||||
function takesFlags(int $flags) : void {
|
||||
echo $flags;
|
||||
}
|
||||
|
||||
takesFlags(FileFlag::MODIFIED | FileFlag::NEW);'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -49,8 +49,8 @@ class Php56Test extends TestCase
|
||||
$c4 = (new C)->four;',
|
||||
'assertions' => [
|
||||
'$c1' => 'int',
|
||||
'$c2' => 'positive-int',
|
||||
'$c3' => 'positive-int',
|
||||
'$c2===' => 'int(2)',
|
||||
'$c3===' => 'int(3)',
|
||||
'$c1_3rd' => 'float|int',
|
||||
'$c_sentence' => 'string',
|
||||
'$cf' => 'int',
|
||||
|
Loading…
Reference in New Issue
Block a user