diff --git a/packages/BetterPhpDocParser/tests/PhpDocInfo/PhpDocInfoPrinterSource/doc15.txt b/packages/BetterPhpDocParser/tests/PhpDocInfo/PhpDocInfoPrinterSource/doc15.txt new file mode 100644 index 000000000000..96344fd28559 --- /dev/null +++ b/packages/BetterPhpDocParser/tests/PhpDocInfo/PhpDocInfoPrinterSource/doc15.txt @@ -0,0 +1,6 @@ +/** + * Stage constructor. + * + * @param string $stage + * @param boolean $undefined Should the object be undefined? + */ \ No newline at end of file diff --git a/packages/BetterPhpDocParser/tests/PhpDocInfo/PhpDocInfoPrinterTest.php b/packages/BetterPhpDocParser/tests/PhpDocInfo/PhpDocInfoPrinterTest.php index 35cfb3948113..223f51ab144a 100644 --- a/packages/BetterPhpDocParser/tests/PhpDocInfo/PhpDocInfoPrinterTest.php +++ b/packages/BetterPhpDocParser/tests/PhpDocInfo/PhpDocInfoPrinterTest.php @@ -67,6 +67,7 @@ public function provideDocFilesForPrint(): Iterator yield [__DIR__ . '/PhpDocInfoPrinterSource/doc12.txt']; yield [__DIR__ . '/PhpDocInfoPrinterSource/doc13.txt']; yield [__DIR__ . '/PhpDocInfoPrinterSource/doc14.txt']; + yield [__DIR__ . '/PhpDocInfoPrinterSource/doc15.txt']; } public function provideMultiline(): Iterator diff --git a/packages/Php/src/Exception/BreakScopeException.php b/packages/Php/src/Exception/BreakScopeException.php new file mode 100644 index 000000000000..784da09f12de --- /dev/null +++ b/packages/Php/src/Exception/BreakScopeException.php @@ -0,0 +1,9 @@ +undefinedVariables = []; - $this->callableNodeTraverser->traverseNodesWithCallable((array) $node->stmts, function (Node $node) { - if (! $node instanceof Variable) { - return null; - } - - if ($this->shouldSkipVariable($node)) { - return null; - } - - $variableName = $this->getName($node); - if ($variableName === null) { - return null; - } - - // defined 100 % - /** @var Scope $nodeScope */ - $nodeScope = $node->getAttribute(AttributeKey::SCOPE); - if ($nodeScope->hasVariableType($variableName)->yes()) { - return null; - } - - // @todo improve - $this->undefinedVariables[] = $variableName; - }); + try { + $this->callableNodeTraverser->traverseNodesWithCallable((array) $node->stmts, function (Node $node) { + // entering new scope - break! + if ($node instanceof FunctionLike) { + throw new BreakScopeException(); + } + + if (! $node instanceof Variable) { + return null; + } + + if ($this->shouldSkipVariable($node)) { + return null; + } + + $variableName = $this->getName($node); + if ($variableName === null) { + return null; + } + + // defined 100 % + /** @var Scope $nodeScope */ + $nodeScope = $node->getAttribute(AttributeKey::SCOPE); + if ($nodeScope->hasVariableType($variableName)->yes()) { + return null; + } + + $this->undefinedVariables[] = $variableName; + }); + } catch (BreakScopeException $breakScopeException) { + // nothing + } if ($this->undefinedVariables === []) { return null;