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

Add check for array access on invalid type

This commit is contained in:
Matthew Brown 2016-11-21 16:44:35 -05:00
parent e9ea66f21b
commit 05a004c8bc
4 changed files with 19 additions and 39 deletions

View File

@ -314,9 +314,9 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
public function getMethodId()
{
if ($this->function instanceof ClassMethod) {
$function_name = $this->function->name;
$function_name = (string)$this->function->name;
if (strtolower($function_name) === strtolower($this->class_name)) {
if (strtolower($function_name) === strtolower((string)$this->class_name)) {
$function_name = '__construct';
}

View File

@ -172,12 +172,12 @@ class MethodChecker extends FunctionLikeChecker
*/
public static function extractReflectionMethodInfo(\ReflectionMethod $method)
{
if (strtolower($method->name) === strtolower((string)$method->class)) {
if (strtolower((string)$method->name) === strtolower((string)$method->class)) {
$method_id = $method->class . '::__construct';
self::$cased_method_ids[$method_id] = $method->class . '::__construct';
}
else {
$method_id = $method->class . '::' . strtolower($method->name);
$method_id = $method->class . '::' . strtolower((string)$method->name);
self::$cased_method_ids[$method_id] = $method->class . '::' . $method->name;
}

View File

@ -903,6 +903,21 @@ class FetchChecker
}
$stmt->inferredType = Type::getString();
} elseif ($type->isNull()) {
// @todo emit NullArrayAccess issue
} elseif ($type->isMixed()) {
// @todo emit MixedArrayAccess issue
} elseif ($type->value && !ClassChecker::classImplements($type->value, 'ArrayAccess')) {
if (IssueBuffer::accepts(
new InvalidArrayAccess(
'Cannot access value on non-array variable ' . $var_id . ' of type ' . $var_type,
$statements_checker->getCheckedFileName(),
$stmt->getLine()
),
$statements_checker->getSuppressedIssues()
)) {
return false;
}
}
}
}

View File

@ -511,41 +511,6 @@ class StatementsChecker
}
}
/**
* @param string $call
* @param PhpParser\Node\Arg[] $args
* @param string $method_id
* @return string|null
*/
protected static function getMethodFromCallBlock($call, array $args, $method_id)
{
$fq_class_name = explode('::', $method_id)[0];
$original_call = $call;
$call = preg_replace('/^\$this(->|::)/', $fq_class_name . '::', $call);
$call = preg_replace('/\(\)$/', '', $call);
if (strpos($call, '$') !== false) {
$method_params = MethodChecker::getMethodParams($method_id);
foreach ($args as $i => $arg) {
$method_param = $method_params[$i];
$preg_var_name = preg_quote('$' . $method_param['name']);
if (preg_match('/::' . $preg_var_name . '$/', $call)) {
if ($arg->value instanceof PhpParser\Node\Scalar\String_) {
$call = preg_replace('/' . $preg_var_name . '$/', $arg->value->value, $call);
break;
}
}
}
}
return $original_call === $call || strpos($call, '$') !== false ? null : $call;
}
/**
* @param PhpParser\Node\Stmt\Const_ $stmt
* @param Context $context