Skip to content

Commit

Permalink
Add Type::getIntRange
Browse files Browse the repository at this point in the history
  • Loading branch information
robchett committed Jun 17, 2023
1 parent 5cb02c9 commit b39b1af
Show file tree
Hide file tree
Showing 12 changed files with 49 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -815,11 +815,9 @@ private static function analyzeOperands(
if ($right_type_part instanceof TLiteralInt) {
$literal_value_max = $right_type_part->value - 1;
if ($always_positive) {
$result_type = new Union([new TIntRange(0, $literal_value_max)]);
$result_type = Type::getIntRange(0, $literal_value_max);
} else {
$result_type = new Union(
[new TIntRange(-$literal_value_max, $literal_value_max)],
);
$result_type = Type::getIntRange(-$literal_value_max, $literal_value_max);
}
} else {
if ($always_positive) {
Expand All @@ -830,7 +828,7 @@ private static function analyzeOperands(
}
} else {
$result_type = Type::combineUnionTypes(
$always_positive ? new Union([new TIntRange(1, null)]) : Type::getInt(true),
$always_positive ? Type::getIntRange(1, null) : Type::getInt(true),
$result_type,
);
}
Expand Down Expand Up @@ -1072,7 +1070,7 @@ private static function analyzeOperandsBetweenIntRange(
$min_value = $calculated_min_type !== null ? $calculated_min_type->getSingleIntLiteral()->value : null;
$max_value = $calculated_max_type !== null ? $calculated_max_type->getSingleIntLiteral()->value : null;

$new_result_type = new Union([new TIntRange($min_value, $max_value)]);
$new_result_type = Type::getIntRange($min_value, $max_value);

$result_type = Type::combineUnionTypes($new_result_type, $result_type);
}
Expand Down Expand Up @@ -1122,7 +1120,7 @@ private static function analyzeMulBetweenIntRange(
$min_value = min($x_1 * $y_1, $x_1 * $y_2, $x_2 * $y_1, $x_2 * $y_2);
$max_value = max($x_1 * $y_1, $x_1 * $y_2, $x_2 * $y_1, $x_2 * $y_2);

$new_result_type = new Union([new TIntRange($min_value, $max_value)]);
$new_result_type = Type::getIntRange($min_value, $max_value);
} elseif ($right_type_part->isPositiveOrZero() && $left_type_part->isPositiveOrZero()) {
// both operands are positive, result will be only positive
$min_operand1 = $left_type_part->min_bound;
Expand Down Expand Up @@ -1156,7 +1154,7 @@ private static function analyzeMulBetweenIntRange(
$min_value = $calculated_min_type !== null ? $calculated_min_type->getSingleIntLiteral()->value : null;
$max_value = $calculated_max_type !== null ? $calculated_max_type->getSingleIntLiteral()->value : null;

$new_result_type = new Union([new TIntRange($min_value, $max_value)]);
$new_result_type = Type::getIntRange($min_value, $max_value);
} elseif ($right_type_part->isPositiveOrZero() && $left_type_part->isNegativeOrZero()) {
// one operand is negative, result will be negative and we have to check min vs max
$min_operand1 = $left_type_part->max_bound;
Expand Down Expand Up @@ -1194,7 +1192,7 @@ private static function analyzeMulBetweenIntRange(
[$min_value, $max_value] = [$max_value, $min_value];
}

$new_result_type = new Union([new TIntRange($min_value, $max_value)]);
$new_result_type = Type::getIntRange($min_value, $max_value);
} elseif ($right_type_part->isNegativeOrZero() && $left_type_part->isPositiveOrZero()) {
// one operand is negative, result will be negative and we have to check min vs max
$min_operand1 = $left_type_part->min_bound;
Expand Down Expand Up @@ -1232,7 +1230,7 @@ private static function analyzeMulBetweenIntRange(
[$min_value, $max_value] = [$max_value, $min_value];
}

$new_result_type = new Union([new TIntRange($min_value, $max_value)]);
$new_result_type = Type::getIntRange($min_value, $max_value);
} elseif ($right_type_part->isNegativeOrZero() && $left_type_part->isNegativeOrZero()) {
// both operand are negative, result will be positive
$min_operand1 = $left_type_part->max_bound;
Expand Down Expand Up @@ -1266,7 +1264,7 @@ private static function analyzeMulBetweenIntRange(
$min_value = $calculated_min_type !== null ? $calculated_min_type->getSingleIntLiteral()->value : null;
$max_value = $calculated_max_type !== null ? $calculated_max_type->getSingleIntLiteral()->value : null;

$new_result_type = new Union([new TIntRange($min_value, $max_value)]);
$new_result_type = Type::getIntRange($min_value, $max_value);
} else {
$new_result_type = Type::getInt(true);
}
Expand All @@ -1283,7 +1281,7 @@ private static function analyzePowBetweenIntRange(
//If Pow second operand is negative, the result will be float, if it's 0, it will be 1/-1, else positive
if ($left_type_part->isPositive()) {
if ($right_type_part->isPositive()) {
$new_result_type = new Union([new TIntRange(1, null)]);
$new_result_type = Type::getIntRange(1, null);
} elseif ($right_type_part->isNegative()) {
$new_result_type = Type::getFloat();
} elseif ($right_type_part->min_bound === 0 && $right_type_part->max_bound === 0) {
Expand All @@ -1296,9 +1294,9 @@ private static function analyzePowBetweenIntRange(
if ($right_type_part->isPositive()) {
if ($right_type_part->min_bound === $right_type_part->max_bound) {
if ($right_type_part->max_bound % 2 === 0) {
$new_result_type = new Union([new TIntRange(1, null)]);
$new_result_type = Type::getIntRange(1, null);
} else {
$new_result_type = new Union([new TIntRange(null, -1)]);
$new_result_type = Type::getIntRange(null, -1);
}
} else {
$new_result_type = Type::getInt(true);
Expand Down Expand Up @@ -1330,7 +1328,7 @@ private static function analyzePowBetweenIntRange(
if ($right_type_part->min_bound === $right_type_part->max_bound
&& $right_type_part->max_bound % 2 === 0
) {
$new_result_type = new Union([new TIntRange(1, null)]);
$new_result_type = Type::getIntRange(1, null);
} else {
$new_result_type = Type::getInt(true);
}
Expand Down Expand Up @@ -1361,26 +1359,26 @@ private static function analyzeModBetweenIntRange(
if ($left_type_part->isPositiveOrZero()) {
if ($right_type_part->isPositive()) {
$max = $right_type_part->min_bound - 1;
$new_result_type = new Union([new TIntRange(0, $max)]);
$new_result_type = Type::getIntRange(0, $max);
} else {
$max = $right_type_part->min_bound + 1;
$new_result_type = new Union([new TIntRange($max, 0)]);
$new_result_type = Type::getIntRange($max, 0);
}
} elseif ($left_type_part->isNegativeOrZero()) {
if ($right_type_part->isPositive()) {
$max = $right_type_part->min_bound - 1;
$new_result_type = new Union([new TIntRange(-$max, 0)]);
$new_result_type = Type::getIntRange(-$max, 0);
} else {
$max = $right_type_part->min_bound + 1;
$new_result_type = new Union([new TIntRange(-$max, 0)]);
$new_result_type = Type::getIntRange(-$max, 0);
}
} else {
if ($right_type_part->isPositive()) {
$max = $right_type_part->min_bound - 1;
} else {
$max = -$right_type_part->min_bound - 1;
}
$new_result_type = new Union([new TIntRange(-$max, $max)]);
$new_result_type = Type::getIntRange(-$max, $max);
}
}
} elseif ($right_type_part->isPositive()) {
Expand All @@ -1394,15 +1392,15 @@ private static function analyzeModBetweenIntRange(
$new_result_type = Type::getListKey();
}
} elseif ($left_type_part->isNegativeOrZero()) {
$new_result_type = new Union([new TIntRange(null, 0)]);
$new_result_type = Type::getIntRange(null, 0);
} else {
$new_result_type = Type::getInt(true);
}
} elseif ($right_type_part->isNegative()) {
if ($left_type_part->isPositiveOrZero()) {
$new_result_type = new Union([new TIntRange(null, 0)]);
$new_result_type = Type::getIntRange(null, 0);
} elseif ($left_type_part->isNegativeOrZero()) {
$new_result_type = new Union([new TIntRange(null, 0)]);
$new_result_type = Type::getIntRange(null, 0);
} else {
$new_result_type = Type::getInt(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ private static function getReturnTypeFromCallMapWithArgs(
if ($min === $max) {
return new Union([new TLiteralInt($max)]);
}
return new Union([new TIntRange($min, $max)]);
return Type::getIntRange($min, $max);
}

if ($atomic_types['array'] instanceof TArray
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Psalm\Issue\UndefinedConstant;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Union;
use ReflectionProperty;

Expand Down Expand Up @@ -175,7 +174,7 @@ public static function getGlobalConstType(
case 'PHP_INT_SIZE':
case 'PHP_MAXPATHLEN':
case 'PHP_VERSION_ID':
return new Union([new TIntRange(1, null)]);
return Type::getIntRange(1, null);

case 'PHP_FLOAT_EPSILON':
case 'PHP_FLOAT_MAX':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ private static function getGlobalTypeInner(string $var_id, bool $files_full_path
'type' => $str,
'tmp_name' => $str,
'size' => Type::getListKey(),
'error' => new Union([new TIntRange(0, 8)]),
'error' => Type::getIntRange(0, 8),
];

if ($files_full_path) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
Expand Down Expand Up @@ -288,7 +287,7 @@ public static function infer(
}

if ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Line) {
return new Union([new TIntRange(1, null)]);
return Type::getIntRange(1, null);
}

if ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Class_
Expand Down
3 changes: 2 additions & 1 deletion src/Psalm/Internal/Analyzer/Statements/UnsetAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
Expand Down Expand Up @@ -90,7 +91,7 @@ public static function analyze(

if ($atomic_root_type->is_list && !$is_list && is_int($key_value)) {
if ($key_value === 0) {
$list_key = new Union([new TIntRange(1, null)]);
$list_key = Type::getIntRange(1, null);
} elseif ($key_value === 1) {
$list_key = new Union([
new TLiteralInt(0),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Union;
Expand Down Expand Up @@ -99,10 +98,10 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev
) {
return new Union([
new TNonEmptyArray([
new Union([new TIntRange(
Type::getIntRange(
$first_arg_type->getSingleIntLiteral()->value,
$second_arg_type->getSingleIntLiteral()->value,
)]),
),
$value_type_from_third_arg,
]),
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\MethodReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Union;
Expand Down Expand Up @@ -57,10 +56,10 @@ public static function getMethodReturnType(MethodReturnTypeProviderEvent $event)
if (isset($formats[0])) {
$types []= new Union([
new TKeyedArray([
'r' => new Union([new TIntRange(0, 255)]),
'g' => new Union([new TIntRange(0, 255)]),
'b' => new Union([new TIntRange(0, 255)]),
'a' => new Union([new TIntRange(0, 1)]),
'r' => Type::getIntRange(0, 255),
'g' => Type::getIntRange(0, 255),
'b' => Type::getIntRange(0, 255),
'a' => Type::getIntRange(0, 1),
]),
]);
}
Expand All @@ -77,10 +76,10 @@ public static function getMethodReturnType(MethodReturnTypeProviderEvent $event)
if (isset($formats[2])) {
$types []= new Union([
new TKeyedArray([
'r' => new Union([new TIntRange(0, 255)]),
'g' => new Union([new TIntRange(0, 255)]),
'b' => new Union([new TIntRange(0, 255)]),
'a' => new Union([new TIntRange(0, 255)]),
'r' => Type::getIntRange(0, 255),
'g' => Type::getIntRange(0, 255),
'b' => Type::getIntRange(0, 255),
'a' => Type::getIntRange(0, 255),
]),
]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev
return Type::getInt(false, $min_potential_int);
}

return new Union([new TIntRange($min_potential_int, $max_potential_int)]);
return Type::getIntRange($min_potential_int, $max_potential_int);
}

//if we're dealing with non-int elements, just combine them all together
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,6 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev
}
}

return new Union([new TIntRange($min_value, $max_value)]);
return Type::getIntRange($min_value, $max_value);
}
}
10 changes: 9 additions & 1 deletion src/Psalm/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,14 @@ public static function getInt(bool $from_calculation = false, ?int $value = null
]);
}

/**
* @psalm-pure
*/
public static function getIntRange(?int $min, ?int $max): Union
{
return new Union([new TIntRange($min, $max)]);
}

/**
* @psalm-pure
*/
Expand Down Expand Up @@ -495,7 +503,7 @@ public static function getListKey(bool $from_docblock = false): Union
if ($from_docblock) {
return self::$listKeyFromDocblock ??= new Union([new TIntRange(0, null, true)]);
}
return self::$listKey ??= new Union([new TIntRange(0, null)]);
return self::$listKey ??= self::getIntRange(0, null);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Type/Atomic/TKeyedArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ public function getGenericKeyType(bool $possibly_undefined = false): Union
if (count($this->properties) === 1) {
return new Union([new TLiteralInt(0)]);
}
return new Union([new TIntRange(0, count($this->properties)-1)]);
return Type::getIntRange(0, count($this->properties)-1);
}

$key_types = [];
Expand Down

0 comments on commit b39b1af

Please sign in to comment.