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

Forbid any non literal int in int range (except min and max named objects)

This commit is contained in:
Semyon 2022-03-11 17:26:07 +03:00
parent 510456c7c4
commit a7e98f4bfc
2 changed files with 63 additions and 8 deletions

View File

@ -830,19 +830,24 @@ class TypeParser
throw new TypeParseTreeException('Union types are not allowed in int range type');
}
if ($param0_union_types[0] instanceof TNamedObject &&
$param0_union_types[0]->value === TIntRange::BOUND_MAX
) {
throw new TypeParseTreeException("min bound for int range param can't be 'max'");
if (!($param0_union_types[0] instanceof TNamedObject) && !($param0_union_types[0] instanceof TLiteralInt) ||
!($param1_union_types[0] instanceof TNamedObject) && !($param1_union_types[0] instanceof TLiteralInt)) {
throw new TypeParseTreeException('Unsupported parameter');
}
if ($param1_union_types[0] instanceof TNamedObject &&
$param1_union_types[0]->value === TIntRange::BOUND_MIN
) {
throw new TypeParseTreeException("max bound for int range param can't be 'min'");
if ($param0_union_types[0] instanceof TNamedObject
&& $param0_union_types[0]->value !== TIntRange::BOUND_MIN) {
throw new TypeParseTreeException('Unknown named object as a min boundary');
}
if ($param1_union_types[0] instanceof TNamedObject
&& $param1_union_types[0]->value !== TIntRange::BOUND_MAX) {
throw new TypeParseTreeException('Unknown named object as a max boundary');
}
$min_bound = null;
$max_bound = null;
if ($param0_union_types[0] instanceof TLiteralInt) {
$min_bound = $param0_union_types[0]->value;
}

View File

@ -748,6 +748,56 @@ class IntRangeTest extends TestCase
}',
'error_message' => 'DocblockTypeContradiction',
],
'maxSpecifiedAsFirst' => [
'<?php
/**
* @param int<max, 0> $a
*/
function scope(int $a){
return $a;
}',
'error_message' => 'InvalidDocblock',
],
'minSpecifiedAsSecond' => [
'<?php
/**
* @param int<0, min> $a
*/
function scope(int $a){
return $a;
}',
'error_message' => 'InvalidDocblock',
],
'unknownConstant' => [
'<?php
/**
* @param int<0, FOO> $a
*/
function scope(int $a){
return $a;
}',
'error_message' => 'InvalidDocblock',
],
'floatAsABoundary' => [
'<?php
/**
* @param int<0, 5.5> $a
*/
function scope(int $a){
return $a;
}',
'error_message' => 'InvalidDocblock',
],
'stringAsABoundary' => [
'<?php
/**
* @param int<0, "bar"> $a
*/
function scope(int $a){
return $a;
}',
'error_message' => 'InvalidDocblock',
],
];
}
}