mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +01:00
Fix #1024 - add support for filter_var
This commit is contained in:
parent
d3cd81078f
commit
496018f84a
@ -518,6 +518,81 @@ class FunctionChecker extends FunctionLikeChecker
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'filter_var':
|
||||
if (isset($call_args[1]->value->inferredType)
|
||||
&& $call_args[1]->value->inferredType->isSingleIntLiteral()
|
||||
) {
|
||||
$filter_type_type = $call_args[1]->value->inferredType->getSingleIntLiteral();
|
||||
|
||||
$filter_type = null;
|
||||
|
||||
switch ($filter_type_type->value) {
|
||||
case \FILTER_VALIDATE_INT:
|
||||
$filter_type = Type::getInt();
|
||||
break;
|
||||
|
||||
case \FILTER_VALIDATE_FLOAT:
|
||||
$filter_type = Type::getFloat();
|
||||
break;
|
||||
|
||||
case \FILTER_VALIDATE_BOOLEAN:
|
||||
$filter_type = Type::getBool();
|
||||
|
||||
break;
|
||||
|
||||
case \FILTER_VALIDATE_IP:
|
||||
case \FILTER_VALIDATE_MAC:
|
||||
case \FILTER_VALIDATE_REGEXP:
|
||||
case \FILTER_VALIDATE_URL:
|
||||
case \FILTER_VALIDATE_EMAIL:
|
||||
case \FILTER_VALIDATE_DOMAIN:
|
||||
$filter_type = Type::getString();
|
||||
break;
|
||||
}
|
||||
|
||||
$has_object_like = false;
|
||||
|
||||
if (isset($call_args[2]->value->inferredType) && $filter_type) {
|
||||
foreach ($call_args[2]->value->inferredType->getTypes() as $atomic_type) {
|
||||
if ($atomic_type instanceof Type\Atomic\ObjectLike) {
|
||||
$has_object_like = true;
|
||||
|
||||
if (isset($atomic_type->properties['default'])) {
|
||||
$filter_type = Type::combineUnionTypes(
|
||||
$filter_type,
|
||||
$atomic_type->properties['default']
|
||||
);
|
||||
} else {
|
||||
$filter_type->addType(new Type\Atomic\TFalse);
|
||||
}
|
||||
|
||||
if (isset($atomic_type->properties['flags'])
|
||||
&& $atomic_type->properties['flags']->isSingleIntLiteral()
|
||||
) {
|
||||
$filter_flag_type =
|
||||
$atomic_type->properties['flags']->getSingleIntLiteral();
|
||||
|
||||
if ($filter_type->hasBool()
|
||||
&& $filter_flag_type->value === \FILTER_NULL_ON_FAILURE
|
||||
) {
|
||||
$filter_type->addType(new Type\Atomic\TNull);
|
||||
}
|
||||
}
|
||||
} elseif ($atomic_type instanceof Type\Atomic\TLiteralInt) {
|
||||
if ($filter_type->hasBool() && $atomic_type->value === \FILTER_NULL_ON_FAILURE) {
|
||||
$filter_type->addType(new Type\Atomic\TNull);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$has_object_like && $filter_type) {
|
||||
$filter_type->addType(new Type\Atomic\TFalse);
|
||||
}
|
||||
|
||||
return $filter_type ?: Type::getMixed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -982,6 +982,41 @@ class FunctionCallTest extends TestCase
|
||||
'$d' => 'string',
|
||||
],
|
||||
],
|
||||
'filterVar' => [
|
||||
'<?php
|
||||
function filterInt(string $s) : int {
|
||||
$filtered = filter_var($s, FILTER_VALIDATE_INT);
|
||||
if ($filtered === false) {
|
||||
return 0;
|
||||
}
|
||||
return $filtered;
|
||||
}
|
||||
function filterNullableInt(string $s) : ?int {
|
||||
return filter_var($s, FILTER_VALIDATE_INT, ["default" => null]);
|
||||
}
|
||||
function filterIntWithDefault(string $s) : int {
|
||||
return filter_var($s, FILTER_VALIDATE_INT, ["default" => 5]);
|
||||
}
|
||||
function filterBool(string $s) : bool {
|
||||
return filter_var($s, FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
function filterNullableBool(string $s) : ?bool {
|
||||
return filter_var($s, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||
}
|
||||
function filterNullableBoolWithFlagsArray(string $s) : ?bool {
|
||||
return filter_var($s, FILTER_VALIDATE_BOOLEAN, ["flags" => FILTER_NULL_ON_FAILURE]);
|
||||
}
|
||||
function filterFloat(string $s) : float {
|
||||
$filtered = filter_var($s, FILTER_VALIDATE_FLOAT);
|
||||
if ($filtered === false) {
|
||||
return 0.0;
|
||||
}
|
||||
return $filtered;
|
||||
}
|
||||
function filterFloatWithDefault(string $s) : float {
|
||||
return filter_var($s, FILTER_VALIDATE_FLOAT, ["default" => 5.0]);
|
||||
}',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user