Skip to content

Commit

Permalink
Merge pull request #7472 from orklah/intrange
Browse files Browse the repository at this point in the history
remove TPositiveInt usage for TIntRange
  • Loading branch information
orklah committed Jan 23, 2022
2 parents 5e41e14 + a7b72b8 commit c90cffd
Show file tree
Hide file tree
Showing 15 changed files with 31 additions and 212 deletions.
Expand Up @@ -58,7 +58,6 @@
use Psalm\Storage\Assertion\IsNotIdentical;
use Psalm\Storage\Assertion\IsNotLooselyEqual;
use Psalm\Storage\Assertion\IsNotType;
use Psalm\Storage\Assertion\IsPositiveNumeric;
use Psalm\Storage\Assertion\IsType;
use Psalm\Storage\Assertion\NestedAssertions;
use Psalm\Storage\Assertion\NonEmptyCountable;
Expand Down Expand Up @@ -3869,13 +3868,7 @@ private static function getGreaterAssertions(

if ($var_name !== null) {
if ($superior_value_position === self::ASSIGNMENT_TO_RIGHT) {
if ($superior_value_comparison === 0) {
$if_types[$var_name] = [[new IsPositiveNumeric(true), new IsIdentical(new TLiteralInt(0))]];
} elseif ($superior_value_comparison === 1) {
$if_types[$var_name] = [[new IsPositiveNumeric(true)]];
} else {
$if_types[$var_name] = [[new IsGreaterThan($superior_value_comparison)]];
}
$if_types[$var_name] = [[new IsGreaterThan($superior_value_comparison)]];
} else {
$if_types[$var_name] = [[new IsLessThan($superior_value_comparison)]];
}
Expand Down Expand Up @@ -3984,13 +3977,7 @@ private static function getSmallerAssertions(
if ($inferior_value_position === self::ASSIGNMENT_TO_RIGHT) {
$if_types[$var_name] = [[new IsLessThan($inferior_value_comparison)]];
} else {
if ($inferior_value_comparison === 0) {
$if_types[$var_name] = [[new IsPositiveNumeric(false), new IsIdentical(new TLiteralInt(0))]];
} elseif ($inferior_value_comparison === 1) {
$if_types[$var_name] = [[new IsPositiveNumeric(true)]];
} else {
$if_types[$var_name] = [[new IsGreaterThan($inferior_value_comparison)]];
}
$if_types[$var_name] = [[new IsGreaterThan($inferior_value_comparison)]];
}

if ($isset_assert) {
Expand Down
Expand Up @@ -28,6 +28,7 @@
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TLowercaseString;
Expand Down Expand Up @@ -202,8 +203,7 @@ public static function analyze(
);

if ($left_is_numeric) {
$right_uint = Type::getPositiveInt();
$right_uint->addType(new TLiteralInt(0));
$right_uint = new Union([new TIntRange(0, null)]);
$right_is_uint = UnionTypeComparator::isContainedBy(
$codebase,
$right_type,
Expand Down
Expand Up @@ -547,7 +547,7 @@ public static function handleByRefArrayAdjustment(
]
);
} else {
/** @psalm-suppress PropertyTypeCoercion */
/** @psalm-suppress InvalidPropertyAssignmentValue */
$array_atomic_type->count--;
}
} else {
Expand All @@ -565,7 +565,7 @@ public static function handleByRefArrayAdjustment(
]
);
} else {
/** @psalm-suppress PropertyTypeCoercion */
/** @psalm-suppress InvalidPropertyAssignmentValue */
$array_atomic_type->count--;
}
} else {
Expand Down
Expand Up @@ -16,6 +16,7 @@
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 @@ -174,7 +175,7 @@ public static function getGlobalConstType(
case 'PHP_INT_SIZE':
case 'PHP_MAXPATHLEN':
case 'PHP_VERSION_ID':
return Type::getPositiveInt();
return new Union([new TIntRange(1, null)]);

case 'PHP_FLOAT_EPSILON':
case 'PHP_FLOAT_MAX':
Expand Down
5 changes: 0 additions & 5 deletions src/Psalm/Internal/Type/NegatedAssertionReconciler.php
Expand Up @@ -11,7 +11,6 @@
use Psalm\Storage\Assertion\IsClassNotEqual;
use Psalm\Storage\Assertion\IsNotCountable;
use Psalm\Storage\Assertion\IsNotIdentical;
use Psalm\Storage\Assertion\IsNotPositiveNumeric;
use Psalm\Storage\Assertion\IsNotType;
use Psalm\Type;
use Psalm\Type\Atomic;
Expand Down Expand Up @@ -91,10 +90,6 @@ public static function reconcile(
);
}

if ($is_equality && $assertion instanceof IsNotPositiveNumeric) {
return $existing_var_type;
}

$existing_var_atomic_types = $existing_var_type->getAtomicTypes();

if ($assertion_type instanceof TFalse && isset($existing_var_atomic_types['bool'])) {
Expand Down
96 changes: 0 additions & 96 deletions src/Psalm/Internal/Type/SimpleAssertionReconciler.php
Expand Up @@ -22,7 +22,6 @@
use Psalm\Storage\Assertion\IsIsset;
use Psalm\Storage\Assertion\IsLessThan;
use Psalm\Storage\Assertion\IsLooselyEqual;
use Psalm\Storage\Assertion\IsPositiveNumeric;
use Psalm\Storage\Assertion\IsType;
use Psalm\Storage\Assertion\NonEmpty;
use Psalm\Storage\Assertion\NonEmptyCountable;
Expand All @@ -40,7 +39,6 @@
use Psalm\Type\Atomic\TCallableString;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TInt;
Expand All @@ -63,7 +61,6 @@
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNonFalsyString;
use Psalm\Type\Atomic\TNonspecificLiteralString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TObject;
Expand All @@ -81,7 +78,6 @@
use function count;
use function explode;
use function get_class;
use function max;
use function min;
use function strpos;

Expand Down Expand Up @@ -238,19 +234,6 @@ public static function reconcile(
);
}

if ($assertion instanceof IsPositiveNumeric) {
return self::reconcilePositiveNumeric(
$assertion,
$existing_var_type,
$key,
$negated,
$code_location,
$suppressed_issues,
$failed_reconciliation,
$is_equality
);
}

if ($assertion instanceof NonEmptyCountable) {
return self::reconcileNonEmptyCountable(
$assertion,
Expand Down Expand Up @@ -725,85 +708,6 @@ private static function reconcileExactlyCountable(
return $existing_var_type;
}

/**
* @param string[] $suppressed_issues
* @param Reconciler::RECONCILIATION_* $failed_reconciliation
*/
private static function reconcilePositiveNumeric(
Assertion $assertion,
Union $existing_var_type,
?string $key,
bool $negated,
?CodeLocation $code_location,
array $suppressed_issues,
int &$failed_reconciliation,
bool $is_equality
): Union {
$old_var_type_string = $existing_var_type->getId();

$did_remove_type = false;

$positive_types = [];

foreach ($existing_var_type->getAtomicTypes() as $atomic_type) {
if ($atomic_type instanceof TLiteralInt) {
if ($atomic_type->value < 1) {
$did_remove_type = true;
} else {
$positive_types[] = $atomic_type;
}
} elseif ($atomic_type instanceof TPositiveInt) {
$positive_types[] = $atomic_type;
} elseif ($atomic_type instanceof TIntRange) {
if (!$atomic_type->isPositive()) {
$did_remove_type = true;
}
$positive_types[] = new TIntRange(
$atomic_type->min_bound === null ? 1 : max(1, $atomic_type->min_bound),
$atomic_type->max_bound === null ? null : max(1, $atomic_type->max_bound)
);
} elseif (get_class($atomic_type) === TInt::class) {
$positive_types[] = new TPositiveInt();
$did_remove_type = true;
} else {
// for now allow this check everywhere else
if (!$atomic_type instanceof TNull
&& !$atomic_type instanceof TFalse
) {
$positive_types[] = $atomic_type;
}

$did_remove_type = true;
}
}

if (!$is_equality
&& !$existing_var_type->hasMixed()
&& (!$did_remove_type || !$positive_types)
) {
if ($key && $code_location) {
self::triggerIssueForImpossible(
$existing_var_type,
$old_var_type_string,
$key,
$assertion,
!$did_remove_type,
$negated,
$code_location,
$suppressed_issues
);
}
}

if ($positive_types) {
return new Union($positive_types);
}

$failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;

return Type::getNever();
}

/**
* @param string[] $suppressed_issues
* @param Reconciler::RECONCILIATION_* $failed_reconciliation
Expand Down
30 changes: 0 additions & 30 deletions src/Psalm/Storage/Assertion/IsNotPositiveNumeric.php

This file was deleted.

38 changes: 0 additions & 38 deletions src/Psalm/Storage/Assertion/IsPositiveNumeric.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Psalm/Type/Atomic.php
Expand Up @@ -210,7 +210,7 @@ public static function create(
return new TClosedResource();

case 'positive-int':
return new TPositiveInt();
return new TIntRange(1, null);

case 'numeric':
return $analysis_php_version_id !== null ? new TNamedObject($value) : new TNumeric();
Expand Down
8 changes: 4 additions & 4 deletions tests/ClosureTest.php
Expand Up @@ -418,7 +418,7 @@ public function test() : Closure {
$closure = Closure::fromCallable("strlen");
',
'assertions' => [
'$closure' => 'pure-Closure(string):(int|positive-int)',
'$closure' => 'pure-Closure(string):int<0, max>',
]
],
'allowClosureWithNarrowerReturn' => [
Expand Down Expand Up @@ -583,8 +583,8 @@ function maker(string $className) {
$result = $closure("test");
',
'assertions' => [
'$closure' => 'pure-Closure(string):(int|positive-int)',
'$result' => 'int|positive-int',
'$closure' => 'pure-Closure(string):int<0, max>',
'$result' => 'int<0, max>',
],
'ignored_issues' => [],
'php_version' => '8.1'
Expand Down Expand Up @@ -660,7 +660,7 @@ public function __invoke(string $param): int {
$closure = $closure(...);
',
'assertions' => [
'$closure' => 'pure-Closure(string):(int|positive-int)',
'$closure' => 'pure-Closure(string):int<0, max>',
],
'ignored_issues' => [],
'php_version' => '8.1'
Expand Down
8 changes: 4 additions & 4 deletions tests/FunctionCallTest.php
Expand Up @@ -48,9 +48,9 @@ function fooFoo(array $a = []): void {
$c = $_GET["c"];
$c = is_numeric($c) ? abs($c) : null;',
'assertions' => [
'$a' => 'int|positive-int',
'$a' => 'int<0, max>',
'$b' => 'float',
'$c' => 'float|int|null|positive-int',
'$c' => 'float|int<0, max>|null',
],
'ignored_issues' => ['MixedAssignment', 'MixedArgument'],
],
Expand Down Expand Up @@ -1362,7 +1362,7 @@ function takesInt(int $i) : void {}
$r = preg_match("{foo}", "foo", $matches, PREG_OFFSET_CAPTURE);',
'assertions' => [
'$r===' => '0|1|false',
'$matches===' => 'array<array-key, array{string, int}>',
'$matches===' => 'array<array-key, array{string, int<-1, max>}>',
],
],
'pregMatchWithFlagUnmatchedAsNull' => [
Expand All @@ -1378,7 +1378,7 @@ function takesInt(int $i) : void {}
$r = preg_match("{foo}", "foo", $matches, PREG_OFFSET_CAPTURE | PREG_UNMATCHED_AS_NULL);',
'assertions' => [
'$r===' => '0|1|false',
'$matches===' => 'array<array-key, array{null|string, int}>',
'$matches===' => 'array<array-key, array{null|string, int<-1, max>}>',
],
],
'pregReplaceCallback' => [
Expand Down

0 comments on commit c90cffd

Please sign in to comment.