From 0aa4d35fd1bb31204ae6cd134c1938c65879c2c1 Mon Sep 17 00:00:00 2001 From: Bruce Weirdan Date: Tue, 1 May 2018 17:09:36 +0300 Subject: [PATCH] Don't ignore files with `use function` Previously `ClassFileLocator` would enter a "function context" when it encountered `T_FUNCTION` token, causing it to ignore subsequent classes (thinking they are defined in a function), ultimately leading to the file being ignored because ``ClassFileLocator`` thought there's no (named) classes defined in the file. Now it will additionally check that the `T_FUNCTION` token is not preceded by `T_USE`, fixing the bug. --- CHANGELOG.md | 2 +- src/ClassFileLocator.php | 5 ++++- test/ClassFileLocatorTest.php | 13 +++++++++++++ test/TestAsset/ContainsUseFunction.php | 10 ++++++++++ 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 test/TestAsset/ContainsUseFunction.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a342e7..00e55d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed -- Nothing. +- [#44](https://github.com/zendframework/zend-file/pull/44) fixes an issue where ClassFileLocator would skip the file (otherwise valid class file) containing `use function` ## 2.8.0 - 2018-04-25 diff --git a/src/ClassFileLocator.php b/src/ClassFileLocator.php index 8ac5f32..c224367 100644 --- a/src/ClassFileLocator.php +++ b/src/ClassFileLocator.php @@ -126,7 +126,10 @@ public function accept() } break; case T_FUNCTION: - $inFunctionDeclaration = true; + // `use function` should not enter function context + if ($i < 2 || ! is_array($tokens[$i - 2]) || $tokens[$i - 2][0] !== T_USE) { + $inFunctionDeclaration = true; + } break; case T_TRAIT: case T_CLASS: diff --git a/test/ClassFileLocatorTest.php b/test/ClassFileLocatorTest.php index d4f4b4d..8d176d1 100644 --- a/test/ClassFileLocatorTest.php +++ b/test/ClassFileLocatorTest.php @@ -196,4 +196,17 @@ public function testIgnoresMethodsNamedAfterKeywords() $this->assertEquals($expected, $classNames, '', 0.0, 10, true); } + + public function testIterationFindsClassInAFileWithUseFunction() + { + $locator = new ClassFileLocator(__DIR__); + $found = false; + + foreach ($locator as $file) { + if (preg_match('/ContainsUseFunction\.php$/', $file->getFilename())) { + $found = true; + } + } + $this->assertTrue($found, "Failed to find a file that contains `use function`"); + } } diff --git a/test/TestAsset/ContainsUseFunction.php b/test/TestAsset/ContainsUseFunction.php new file mode 100644 index 0000000..9fbf6d9 --- /dev/null +++ b/test/TestAsset/ContainsUseFunction.php @@ -0,0 +1,10 @@ +