Skip to content
Permalink
Browse files

Fix #2035 more comprehensively

  • Loading branch information...
muglug committed Aug 20, 2019
1 parent f5b6321 commit 17e7fe70c1bfef3d6eef302b7f4f56e44a5620a6
@@ -434,6 +434,52 @@ function (\Psalm\Internal\Clause $c) use ($mixed_var_ids) {
$t_if_context->vars_in_scope = $t_if_vars_in_scope_reconciled;
}
if (!self::hasArrayDimFetch($stmt->left)) {
// check first if the variable was good
IssueBuffer::startRecording();
if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->left, clone $context) === false) {
return false;
}
IssueBuffer::clearRecordingLevel();
IssueBuffer::stopRecording();
$naive_type = $stmt->left->inferredType ?? null;
if ($naive_type
&& !$naive_type->isMixed()
&& !$naive_type->isNullable()
) {
$var_id = ExpressionAnalyzer::getVarId($stmt->left, $context->self);
if (!$var_id || !\in_array($var_id, $changed_var_ids, true)) {
if ($naive_type->from_docblock) {
if (IssueBuffer::accepts(
new \Psalm\Issue\DocblockTypeContradiction(
$naive_type->getId() . ' does not contain null',
new CodeLocation($statements_analyzer, $stmt->left)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
} else {
if (IssueBuffer::accepts(
new \Psalm\Issue\TypeDoesNotContainType(
$naive_type->getId() . ' is always defined and non-null',
new CodeLocation($statements_analyzer, $stmt->left)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
}
}
}
}
$t_if_context->inside_isset = true;
if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->left, $t_if_context) === false) {
@@ -663,6 +709,21 @@ function (\Psalm\Internal\Clause $c) use ($mixed_var_ids) {
return null;
}
private static function hasArrayDimFetch(PhpParser\Node\Expr $expr) : bool
{
if ($expr instanceof PhpParser\Node\Expr\ArrayDimFetch) {
return true;
}
if ($expr instanceof PhpParser\Node\Expr\PropertyFetch
|| $expr instanceof PhpParser\Node\Expr\MethodCall
) {
return self::hasArrayDimFetch($expr->var);
}
return false;
}
/**
* @param StatementsSource|null $statements_source
* @param PhpParser\Node\Expr $left
@@ -79,7 +79,7 @@ protected function fillTravisCi() : self
$this->readEnv['CI_REPO_NAME'] = $slug_parts[1];
}
$pr_slug = (string) $this->env['TRAVIS_PULL_REQUEST_SLUG'] ?? '';
$pr_slug = (string) ($this->env['TRAVIS_PULL_REQUEST_SLUG'] ?? '');
if ($pr_slug) {
$slug_parts = explode('/', $pr_slug);
@@ -150,7 +150,7 @@ protected function fillAppVeyor() : self
$this->readEnv['APPVEYOR_REPO_BRANCH'] = $this->env['APPVEYOR_REPO_BRANCH'];
$this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
$repo_slug = (string) $this->env['APPVEYOR_REPO_NAME'] ?? '';
$repo_slug = (string) ($this->env['APPVEYOR_REPO_NAME'] ?? '');
if ($repo_slug) {
$slug_parts = explode('/', $repo_slug);
@@ -215,7 +215,7 @@ protected function fillScrutinizer() : self
// backup
$this->readEnv['CI_NAME'] = 'Scrutinizer';
$repo_slug = (string) $this->env['SCRUTINIZER_PROJECT'] ?? '';
$repo_slug = (string) ($this->env['SCRUTINIZER_PROJECT'] ?? '');
if ($repo_slug) {
$slug_parts = explode('/', $repo_slug);
@@ -1237,12 +1237,12 @@ function example3(): void {
$glob3->func();
}
namespace {
ord($glob1 ?? "str");
ord($glob1 ?: "str");
ord($_GET["str"] ?? "str");
function example4(): void {
global $glob1;
ord($glob1 ?? "str");
ord($glob1 ?: "str");
ord($_GET["str"] ?? "str");
}
}'
@@ -1468,6 +1468,19 @@ function render(array $data): ?Traversable {
return null;
}'
],
'nullCoalesceTypedArrayValue' => [
'<?php
/** @param string[] $arr */
function foo(array $arr) : string {
return $arr["b"] ?? "bar";
}',
],
'nullCoalesceTypedValue' => [
'<?php
function foo(?string $s) : string {
return $s ?? "bar";
}',
],
];
}
@@ -1752,6 +1765,13 @@ function firstChar(string $s) : string { return $s; }
if (false !== firstChar("sdf")) {}',
'error_message' => 'RedundantCondition',
],
'nullCoalesceImpossible' => [
'<?php
function foo(?string $s) : string {
return ((string) $s) ?? "bar";
}',
'error_message' => 'TypeDoesNotContainType'
],
];
}
}

0 comments on commit 17e7fe7

Please sign in to comment.
You can’t perform that action at this time.