1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Tighten up what array assignments can happen

This commit is contained in:
Matthew Brown 2017-01-02 01:07:44 -05:00
parent 882c8a8d0c
commit 93c1366bd8
12 changed files with 47 additions and 14 deletions

View File

@ -121,8 +121,8 @@ class FileChecker extends SourceChecker implements StatementsSource
public static $storage = [];
/**
* @param string $file_path
* @param array $preloaded_statements
* @param string $file_path
* @param array<int, PhpParser\Node\Expr|PhpParser\Node\Stmt> $preloaded_statements
*/
public function __construct($file_path, array $preloaded_statements = [])
{
@ -461,6 +461,7 @@ class FileChecker extends SourceChecker implements StatementsSource
/**
* @return bool
* @psalm-suppress MixedAssignment
* @psalm-suppress InvalidPropertyAssignment
*/
public static function loadReferenceCache()
{

View File

@ -359,9 +359,20 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
$default_type = StatementsChecker::getSimpleType($parser_param->default);
if ($default_type && !TypeChecker::isContainedBy($default_type, $param_type)) {
$method_id = $this->getMethodId();
$cased_method_id = $method_id;
if ($cased_method_id) {
if ($this instanceof MethodChecker) {
$cased_method_id = MethodChecker::getCasedMethodId($cased_method_id);
} elseif ($this->function instanceof PhpParser\Node\Stmt\Function_) {
$cased_method_id = $this->function->name;
}
}
if (IssueBuffer::accepts(
new InvalidParamDefault(
'Default value for argument ' . ($offset + 1) . ' of method ' . $this->getMethodId() .
'Default value for argument ' . ($offset + 1) . ' of method ' . $cased_method_id .
' does not match the given type ' . $param_type,
$function_param->code_location
)

View File

@ -50,7 +50,7 @@ abstract class SourceChecker implements StatementsSource
protected $include_file_path;
/**
* @var array<string>
* @var array<int, string>
*/
protected $suppressed_issues = [];

View File

@ -509,6 +509,10 @@ class StatementsChecker
} elseif ($stmt instanceof PhpParser\Node\Scalar\DNumber) {
return Type::getFloat();
} elseif ($stmt instanceof PhpParser\Node\Expr\Array_) {
if (count($stmt->items) === 0) {
return Type::getEmptyArray();
}
return Type::getArray();
} elseif ($stmt instanceof PhpParser\Node\Expr\Cast\Int_) {
return Type::getInt();

View File

@ -88,7 +88,7 @@ class TraitChecker extends ClassLikeChecker
}
/**
* @param array $method_map
* @param array<string, string> $method_map
* @return void
*/
public function setMethodMap(array $method_map)

View File

@ -710,9 +710,9 @@ class TypeChecker
) {
if (self::isContainedBy($container_param, $input_param)) {
$type_coerced = true;
} else {
$all_types_contain = false;
}
$all_types_contain = false;
}
}
}

View File

@ -518,6 +518,7 @@ class Config
/**
* @return void
* @psalm-suppress InvalidPropertyAssignment
*/
public function collectPredefinedConstants()
{

View File

@ -27,7 +27,7 @@ class FunctionDocblockComment
public $variadic = false;
/**
* @var array<string>
* @var array<int, string>
*/
public $suppress = [];

View File

@ -9,7 +9,7 @@ class IfScope
public $new_vars = null;
/**
* @var array<string, boolean>
* @var array<string, boolean|string>
*/
public $new_vars_possibly_in_scope = [];

View File

@ -14,21 +14,21 @@ interface StatementsSource
public function getAliasedClasses();
/**
* @return array<string>
* @return array<string, string>
*/
public function getAliasedClassesFlipped();
/**
* Gets a list of all aliased constants
*
* @return array
* @return array<string, string>
*/
public function getAliasedConstants();
/**
* Gets a list of all aliased functions
*
* @return array
* @return array<string, string>
*/
public function getAliasedFunctions();
@ -101,7 +101,7 @@ interface StatementsSource
/**
* Get a list of suppressed issues
*
* @return array<string>
* @return array<int, string>
*/
public function getSuppressedIssues();
}

View File

@ -125,4 +125,20 @@ class FunctionCallTest extends PHPUnit_Framework_TestCase
$context = new Context('somefile.php');
$file_checker->check(true, true, $context);
}
public function testTypedArrayWithDefault()
{
$stmts = self::$parser->parse('<?php
class A {}
/** @param array<A> $a */
function fooFoo(array $a = []) : void {
}
');
$file_checker = new FileChecker('somefile.php', $stmts);
$context = new Context('somefile.php');
$file_checker->check(true, true, $context);
}
}

View File

@ -502,7 +502,7 @@ class PropertyTypeTest extends PHPUnit_Framework_TestCase
}
$c = new C;
$c->bb = [new A];
$c->bb = [new A, new B];
');
$file_checker = new \Psalm\Checker\FileChecker('somefile.php', $stmts);