From 2b7d340c6f03ef18eed5a6712b3a64200143ac27 Mon Sep 17 00:00:00 2001 From: Philip Nelson Date: Thu, 28 Dec 2017 08:21:44 +1100 Subject: [PATCH] don't check foreach keys/values when we come from the foreach collection --- fixtures/completion/foreach.php | 7 +++++++ src/DefinitionResolver.php | 21 +++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/fixtures/completion/foreach.php b/fixtures/completion/foreach.php index b6fa5be..c7fc65b 100644 --- a/fixtures/completion/foreach.php +++ b/fixtures/completion/foreach.php @@ -38,3 +38,10 @@ foreach ($bar->test() as $value) { foreach ($unknownArray as $unknown) { $unkno +} + +foreach ($loop as $loop) { +} + +foreach ($loop->getArray() as $loop) { +} diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index a408dd4..43f8a09 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -571,10 +571,27 @@ class DefinitionResolver // If we get to a ForeachStatement, check the keys and values if ($n instanceof Node\Statement\ForeachStatement) { - if ($n->foreachKey && $n->foreachKey->expression->getName() === $name) { + // Only check keys and values if we did not get here from the foreach collection, otherwise code like + // foreach ($a as $a) will send us in circles + $isForeachCollection = false; + if ($n->forEachCollectionName) { + if ($n->forEachCollectionName === $var) { + $isForeachCollection = true; + } else { + foreach ($n->forEachCollectionName->getDescendantNodes() as $childNode) { + if ($childNode === $var) { + $isForeachCollection = true; + break; + } + } + } + } + if (!$isForeachCollection && $n->foreachKey instanceof Node\Expression\Variable + && $n->foreachKey->expression->getName() === $name + ) { return $n->foreachKey; } - if ($n->foreachValue + if (!$isForeachCollection && $n->foreachValue && $n->foreachValue->expression instanceof Node\Expression\Variable && $n->foreachValue->expression->getName() === $name ) {