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:
parent
882c8a8d0c
commit
93c1366bd8
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -50,7 +50,7 @@ abstract class SourceChecker implements StatementsSource
|
||||
protected $include_file_path;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $suppressed_issues = [];
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -518,6 +518,7 @@ class Config
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @psalm-suppress InvalidPropertyAssignment
|
||||
*/
|
||||
public function collectPredefinedConstants()
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ class FunctionDocblockComment
|
||||
public $variadic = false;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public $suppress = [];
|
||||
|
||||
|
@ -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 = [];
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user