Skip to content

Commit

Permalink
Fix tests, add a few limits
Browse files Browse the repository at this point in the history
  • Loading branch information
danog committed May 10, 2021
1 parent 05f1121 commit 8a8b71e
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 20 deletions.
1 change: 0 additions & 1 deletion src/Psalm/Internal/Codebase/Scanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use const PHP_EOL;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\ErrorHandler;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
Expand Down
21 changes: 17 additions & 4 deletions src/Psalm/Internal/Provider/FunctionReturnTypeProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
namespace Psalm\Internal\Provider;

use PhpParser;
use PhpParser\Node\Arg;
use Psalm\Codebase;
use Psalm\CodeLocation;
use Psalm\Context;
Expand All @@ -15,7 +14,6 @@
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TEmpty;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
Expand All @@ -32,6 +30,7 @@
use function is_subclass_of;
use function function_exists;
use function is_array;
use function strlen;

class FunctionReturnTypeProvider
{
Expand Down Expand Up @@ -499,14 +498,20 @@ function_exists($function_id) &&
$required <= count($type_args) &&
(count($type_args) <= count($callable->params) || $variadic)
) {
$maxStrLen = \Psalm\Config::getInstance()->max_string_length;
foreach ($this->permutateArguments(
$callable->params,
$type_args,
$codebase,
$has_leftover
) as $args) {
try {
if ($function_id === 'array_combine' && count($args[0]) !== count($args[1])) {
if (($function_id === 'array_combine' && count($args[0]) !== count($args[1])) ||
($function_id === 'str_repeat' && (strlen($args[0]) * $args[1]) >= $maxStrLen) ||
($function_id === 'str_pad' && $args[1] >= $maxStrLen) ||
($function_id === 'array_pad' && $args[1] > 100) ||
($function_id === 'array_fill' && $args[1] > 100)
) {
$has_leftover = true;
continue;
}
Expand Down Expand Up @@ -655,6 +660,9 @@ public static function extractLiterals(
bool &$has_leftover
): array {
$values = [];
if ($type->possibly_undefined) {
$has_leftover = true;
}
foreach ($type->getAtomicTypes() as $atomic_key_type) {
if ($atomic_key_type instanceof TLiteralString) {
$values []= $atomic_key_type->value;
Expand All @@ -670,8 +678,13 @@ public static function extractLiterals(
$values []= null;
} elseif ($atomic_key_type instanceof TKeyedArray) {
$skip = false;
$possibly_undefined = false;
$array = [];
foreach ($atomic_key_type->properties as $key => $sub) {
if ($sub->possibly_undefined) {
$possibly_undefined = true;
continue;
}
$res = self::extractLiterals($sub, $skip);
if (count($res) !== 1) {
$skip = true;
Expand All @@ -681,7 +694,7 @@ public static function extractLiterals(
}
if ($skip) {
$has_leftover = true;
} else {
} elseif ($array || !$possibly_undefined) {
$values []= $array;
}
} elseif ($atomic_key_type instanceof TList) {
Expand Down
1 change: 0 additions & 1 deletion src/Psalm/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
use function substr;
use function gettype;
use function is_array;
use function array_map;

abstract class Type
{
Expand Down
24 changes: 19 additions & 5 deletions tests/ArrayAssignmentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -833,9 +833,9 @@ public function offsetSet($offset, $value): void
$a_values = array_values($a);
$a_keys = array_keys($a);',
'assertions' => [
'$a' => 'array{"hello", 5}',
'$a_values' => 'array{0: "hello", 1: 5}',
'$a_keys' => 'array{0: 0, 1: 1}',
'$a===' => 'array{"hello", 5}',
'$a_values===' => 'array{0: "hello", 1: 5}',
'$a_keys===' => 'array{0: 0, 1: 1}',
],
],
'changeIntOffsetKeyValuesWithDirectAssignment' => [
Expand All @@ -858,13 +858,27 @@ public function offsetSet($offset, $value): void
],
'mergeIntOffsetValues' => [
'<?php
$d = array_merge(["hello", 5], []);
$e = array_merge(["hello", 5], ["hello again"]);',
/**
* @var array{string, int} $a
* @var array<empty, empty> $b
* @var array{string} $c
*/
$d = array_merge($a, $b);
$e = array_merge($a, $c);',
'assertions' => [
'$d' => 'array{0: string, 1: int}',
'$e' => 'array{0: string, 1: int, 2: string}',
],
],
'mergeIntOffsetValuesLiteral' => [
'<?php
$d = array_merge(["hello", 5], []);
$e = array_merge(["hello", 5], ["hello again"]);',
'assertions' => [
'$d===' => 'array{0: "hello", 1: 5}',
'$e===' => 'array{0: "hello", 1: 5, 2: "hello again"}',
],
],
'addIntOffsetToEmptyArray' => [
'<?php
$f = [];
Expand Down
2 changes: 1 addition & 1 deletion tests/BinaryOperationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public function providerValidCodeParse(): iterable
],
'numericAddition' => [
'<?php
$a = "5";
/** @var string $a */
if (is_numeric($a)) {
$b = $a + 4;
Expand Down
57 changes: 51 additions & 6 deletions tests/FunctionCallTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -551,16 +551,37 @@ function getString() : string {
return rand(0, 1) ? "==" : "=";
}
$a = version_compare("5.0.0", "7.0.0");
$b = version_compare("5.0.0", "7.0.0", "==");
$c = version_compare("5.0.0", "7.0.0", getString());
/**
* @var string $f
* @var string $s
*/
$a = version_compare($f, $s);
$b = version_compare($f, $s, "==");
$c = version_compare($f, $s, getString());
',
'assertions' => [
'$a' => 'int',
'$b' => 'bool',
'$c' => 'bool',
],
],
'versionCompareLiteral' => [
'<?php
/** @return "="|"==" */
function getString() : string {
return rand(0, 1) ? "==" : "=";
}
$a = version_compare("5.0.0", "7.0.0");
$b = version_compare("5.0.0", "7.0.0", "==");
$c = version_compare("5.0.0", "7.0.0", getString());
',
'assertions' => [
'$a===' => '-1',
'$b===' => 'false',
'$c===' => 'false',
],
],
'getTimeOfDay' => [
'<?php
$a = gettimeofday(true) - gettimeofday(true);
Expand Down Expand Up @@ -618,8 +639,8 @@ function portismaybeint(string $s) : ? int {
$porta = parse_url("", PHP_URL_PORT);
$porte = parse_url("localhost:443", PHP_URL_PORT);',
'assertions' => [
'$porta' => 'false|int|null',
'$porte' => 'false|int|null',
'$porta' => 'null',
'$porte===' => '443',
],
'error_levels' => ['MixedReturnStatement', 'MixedInferredReturnType'],
],
Expand All @@ -645,7 +666,7 @@ function bag(string $s) : string {
],
'parseUrlTypes' => [
'<?php
$url = "foo";
/** @var string $url */;
$components = parse_url($url);
$scheme = parse_url($url, PHP_URL_SCHEME);
$host = parse_url($url, PHP_URL_HOST);
Expand All @@ -667,6 +688,30 @@ function bag(string $s) : string {
'$fragment' => 'false|null|string',
],
],
'parseUrlTypesLiteral' => [
'<?php
$url = "http://owo:pwd@google.com:123/a/b/c?v=1#h=2";
$components = parse_url($url);
$scheme = parse_url($url, PHP_URL_SCHEME);
$host = parse_url($url, PHP_URL_HOST);
$port = parse_url($url, PHP_URL_PORT);
$user = parse_url($url, PHP_URL_USER);
$pass = parse_url($url, PHP_URL_PASS);
$path = parse_url($url, PHP_URL_PATH);
$query = parse_url($url, PHP_URL_QUERY);
$fragment = parse_url($url, PHP_URL_FRAGMENT);',
'assertions' => [
'$components===' => 'array{fragment: "h=2", host: "google.com", pass: "pwd", path: "/a/b/c", port: 123, query: "v=1", scheme: "http", user: "owo"}',
'$scheme===' => '"http"',
'$host===' => '"google.com"',
'$port===' => '123',
'$user===' => '"owo"',
'$pass===' => '"pwd"',
'$path===' => '"/a/b/c"',
'$query===' => '"v=1"',
'$fragment===' => '"h=2"',
],
],
'triggerUserError' => [
'<?php
function mightLeave() : string {
Expand Down
2 changes: 1 addition & 1 deletion tests/TypeReconciliation/ConditionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2639,7 +2639,7 @@ class C { }
],
'typeTransformation' => [
'<?php
$a = "5";
/** @var string $a */;
if (is_numeric($a)) {
if (is_int($a)) {
Expand Down
6 changes: 5 additions & 1 deletion tests/TypeReconciliation/TypeAlgebraTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,11 @@ function paradox2(): void {
'<?php
function foo(string $a): void {
if (!$a) {
list($a) = explode(":", "a:b");
/**
* @var string $b
* @var string $c
*/
list($a) = explode($b, $c);
if ($a) { }
}
Expand Down

0 comments on commit 8a8b71e

Please sign in to comment.