1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Convert InvalidScalarArgument to InvalidArgument when declare(strict_types=1) is set

This commit is contained in:
Matt Brown 2018-08-28 12:37:25 -04:00
parent ba87eb069c
commit 1037485a60
6 changed files with 83 additions and 22 deletions

View File

@ -733,6 +733,7 @@ class TypeChecker
if ($input_type_part instanceof Scalar) {
if ($container_type_part instanceof Scalar
&& !$container_type_part->strict
&& !$container_type_part instanceof TLiteralInt
&& !$container_type_part instanceof TLiteralString
&& !$container_type_part instanceof TLiteralFloat

View File

@ -76,12 +76,17 @@ abstract class Type
* @param string $type_string
* @param bool $php_compatible
* @param array<string, string> $template_type_names
* @param bool $strict_types
*
* @return Union
*/
public static function parseString($type_string, $php_compatible = false, array $template_type_names = [])
{
return self::parseTokens(self::tokenize($type_string), $php_compatible, $template_type_names);
public static function parseString(
$type_string,
$php_compatible = false,
array $template_type_names = [],
$strict_types = false
) {
return self::parseTokens(self::tokenize($type_string), $php_compatible, $template_type_names, $strict_types);
}
/**
@ -90,11 +95,16 @@ abstract class Type
* @param array<int, string> $type_tokens
* @param bool $php_compatible
* @param array<string, string> $template_type_names
* @param bool $strict_types
*
* @return Union
*/
public static function parseTokens(array $type_tokens, $php_compatible = false, array $template_type_names = [])
{
public static function parseTokens(
array $type_tokens,
$php_compatible = false,
array $template_type_names = [],
$strict_types = false
) {
if (count($type_tokens) === 1) {
$only_token = $type_tokens[0];
@ -105,7 +115,7 @@ abstract class Type
$only_token = self::fixScalarTerms($only_token, $php_compatible);
return new Union([Atomic::create($only_token, $php_compatible, $template_type_names)]);
return new Union([Atomic::create($only_token, $php_compatible, $template_type_names, $strict_types)]);
}
try {

View File

@ -54,27 +54,56 @@ abstract class Atomic
* @param string $value
* @param bool $php_compatible
* @param array<string, string> $template_type_names
* @param bool $strict_types
*
* @return Atomic
*/
public static function create($value, $php_compatible = false, array $template_type_names = [])
{
public static function create(
$value,
$php_compatible = false,
array $template_type_names = [],
$strict_types = false
) {
switch ($value) {
case 'int':
return new TInt();
$t = new TInt();
if ($strict_types) {
$t->strict = true;
}
return $t;
case 'float':
$t = new TFloat();
if ($strict_types) {
$t->strict = true;
}
return $t;
case 'string':
$t = new TString();
if ($strict_types) {
$t->strict = true;
}
return $t;
case 'bool':
$t = new TBool();
if ($strict_types) {
$t->strict = true;
}
return $t;
case 'void':
return new TVoid();
case 'float':
return new TFloat();
case 'string':
return new TString();
case 'bool':
return new TBool();
case 'object':
return new TObject();

View File

@ -3,6 +3,9 @@ namespace Psalm\Type\Atomic;
abstract class Scalar extends \Psalm\Type\Atomic
{
/** @var true|null */
public $strict;
/**
* @param string|null $namespace
* @param array<string> $aliased_classes

View File

@ -83,6 +83,9 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
/** @var string[] */
private $after_classlike_check_plugins;
/** @var bool */
private $strict_types = false;
/**
* @var array<string, array<int, string>>
*/
@ -450,6 +453,15 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
if ($function_like_storage) {
$function_like_storage->has_yield = true;
}
} elseif ($node instanceof PhpParser\Node\Stmt\Declare_) {
foreach ($node->declares as $declaration) {
if ((string) $declaration->key === 'strict_types'
&& $declaration->value instanceof PhpParser\Node\Scalar\LNumber
&& $declaration->value->value === 1
) {
$this->strict_types = true;
}
}
}
}
@ -1418,11 +1430,11 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
}
if ($param_type_string) {
if ($is_nullable) {
$param_type_string .= '|null';
}
$param_type = Type::parseString($param_type_string, true, [], $this->strict_types);
$param_type = Type::parseString($param_type_string, true);
if ($is_nullable) {
$param_type->addType(new Type\Atomic\TNull);
}
if ($param->variadic) {
$param_type = new Type\Union([

View File

@ -956,6 +956,12 @@ class FunctionCallTest extends TestCase
fooFoo("string");',
'error_message' => 'InvalidScalarArgument',
],
'invalidArgumentWithDeclareStrictTypes' => [
'<?php declare(strict_types=1);
function fooFoo(int $a): void {}
fooFoo("string");',
'error_message' => 'InvalidArgument',
],
'mixedArgument' => [
'<?php
function fooFoo(int $a): void {}