1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Fix location of function param vars

This commit is contained in:
Matthew Brown 2017-12-29 21:28:21 -05:00
parent 37a3c0a81e
commit f81642c1eb
5 changed files with 48 additions and 13 deletions

View File

@ -301,6 +301,7 @@ class FunctionChecker extends FunctionLikeChecker
$by_reference,
$param_type,
null,
null,
$optional,
false,
$variadic

View File

@ -42,6 +42,7 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
{
const RETURN_TYPE_REGEX = '/\\:\s+(\\??[A-Za-z0-9_\\\\\[\]]+)/';
const PARAM_TYPE_REGEX = '/^(\\??[A-Za-z0-9_\\\\\[\]]+)\s/';
const PARAM_TYPE_VAR = '/(\$[^ ]*)/';
/**
* @var Closure|Function_|ClassMethod
@ -287,7 +288,7 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
$context->vars_in_scope['$' . $function_param->name] = $param_type;
$context->vars_possibly_in_scope['$' . $function_param->name] = true;
if (!$function_param->location) {
if (!$function_param->type_location || !$function_param->location) {
continue;
}
@ -309,7 +310,7 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
new InvalidDocblock(
'Parameter $' . $function_param->name . ' has wrong type \'' . $param_type .
'\', should be \'' . $signature_type . '\'',
$function_param->location
$function_param->type_location
),
$storage->suppressed_issues
)) {
@ -334,7 +335,7 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
new InvalidParamDefault(
'Default value for argument ' . ($offset + 1) . ' of method ' . $cased_method_id .
' does not match the given type ' . $param_type,
$function_param->location
$function_param->type_location
)
)) {
// fall through
@ -346,19 +347,25 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
$substituted_type = clone $param_type;
$generic_types = [];
$substituted_type->replaceTemplateTypesWithStandins($template_types, $generic_types, null);
$substituted_type->check($this->source, $function_param->location, $this->suppressed_issues, [], false);
$substituted_type->check(
$this->source,
$function_param->type_location,
$this->suppressed_issues,
[],
false
);
} else {
$param_type->check($this->source, $function_param->location, $this->suppressed_issues, [], false);
$param_type->check($this->source, $function_param->type_location, $this->suppressed_issues, [], false);
}
if ($this->getFileChecker()->project_checker->collect_references) {
if ($function_param->location !== $function_param->signature_location &&
$function_param->signature_location &&
if ($function_param->type_location !== $function_param->signature_type_location &&
$function_param->signature_type_location &&
$function_param->signature_type
) {
$function_param->signature_type->check(
$this->source,
$function_param->signature_location,
$function_param->signature_type_location,
$this->suppressed_issues,
[],
false
@ -1281,6 +1288,7 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
(bool)$param->isPassedByReference(),
$param_type,
null,
null,
$is_optional,
$is_nullable,
$param->isVariadic()

View File

@ -41,7 +41,12 @@ class FunctionLikeParameter
/**
* @var CodeLocation|null
*/
public $signature_location;
public $type_location;
/**
* @var CodeLocation|null
*/
public $signature_type_location;
/**
* @var bool
@ -62,6 +67,7 @@ class FunctionLikeParameter
$by_ref,
Type\Union $type = null,
CodeLocation $location = null,
CodeLocation $type_location = null,
$is_optional = true,
$is_nullable = false,
$is_variadic = false
@ -74,6 +80,7 @@ class FunctionLikeParameter
$this->is_nullable = $is_nullable;
$this->is_variadic = $is_variadic;
$this->location = $location;
$this->signature_location = $location;
$this->type_location = $type_location;
$this->signature_type_location = $type_location;
}
}

View File

@ -968,7 +968,10 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
$param->name,
$param->byRef,
$param_type,
new CodeLocation($this->file_checker, $param, null, false, FunctionLikeChecker::PARAM_TYPE_REGEX),
new CodeLocation($this->file_checker, $param, null, false, FunctionLikeChecker::PARAM_TYPE_VAR),
$param_typehint
? new CodeLocation($this->file_checker, $param, null, false, FunctionLikeChecker::PARAM_TYPE_REGEX)
: null,
$is_optional,
$is_nullable,
$param->variadic
@ -1067,7 +1070,7 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
}
$storage_param->type = $new_param_type;
$storage_param->location = $code_location;
$storage_param->type_location = $code_location;
continue;
}
@ -1092,7 +1095,7 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
$storage_param->type = new Type\Union(array_values($improved_atomic_types));
$storage_param->type->setFromDocblock();
$storage_param->location = $code_location;
$storage_param->type_location = $code_location;
}
}

View File

@ -29,6 +29,7 @@ class JsonOutputTest extends TestCase
$config->throw_exception = false;
$config->stop_on_first_error = false;
$this->project_checker->setConfig($config);
$this->project_checker->collect_references = true;
}
/**
@ -87,6 +88,7 @@ echo $a;';
$file_checker = new FileChecker('somefile.php', $this->project_checker);
$file_checker->visitAndAnalyzeMethods();
$this->project_checker->checkClassReferences();
$issue_data = IssueBuffer::getIssuesData();
$this->assertSame(
[
@ -132,6 +134,20 @@ echo $a;';
'snippet_to' => 84,
'column' => 10,
],
[
'severity' => 'error',
'line_number' => 2,
'type' => 'UnusedParam',
'message' => 'Param $your_code is never referenced in this method',
'file_name' => 'somefile.php',
'file_path' => 'somefile.php',
'snippet' => 'function psalmCanVerify(int $your_code) : ?string {',
'from' => 34,
'to' => 44,
'snippet_from' => 6,
'snippet_to' => 57,
'column' => 29,
],
[
'severity' => 'error',
'line_number' => 2,