From a2cec18bc457d0f62b02d296ae79ddcc2c4b3f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Wed, 11 Jan 2017 11:29:26 +0100 Subject: [PATCH 1/2] Enhancement: Assert that locator ignores anonymous classes --- test/ClassFileLocatorTest.php | 28 ++++++++++++++++++- .../Anonymous/WithAnonymousClass.php | 24 ++++++++++++++++ .../Anonymous/with-anonymous-class.php | 13 +++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 test/TestAsset/Anonymous/WithAnonymousClass.php create mode 100644 test/TestAsset/Anonymous/with-anonymous-class.php diff --git a/test/ClassFileLocatorTest.php b/test/ClassFileLocatorTest.php index 484a9e1..ee6c9e8 100644 --- a/test/ClassFileLocatorTest.php +++ b/test/ClassFileLocatorTest.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository - * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2017 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ @@ -11,6 +11,7 @@ use Zend\File\ClassFileLocator; use Zend\File\Exception; +use Zend\File\PhpClassFile; /** * Test class for Zend\File\ClassFileLocator @@ -147,4 +148,29 @@ public function testIterationShouldNotCountFQCNScalarResolutionConstantAsClass() $this->assertCount(1, $file->getClasses()); } } + + /** + * @requires PHP 7.1 + */ + public function testIgnoresAnonymousClasses() + { + $classFileLocator = new ClassFileLocator(__DIR__ . '/TestAsset/Anonymous'); + + $classFiles = \iterator_to_array($classFileLocator); + + $this->assertCount(1, $classFiles); + + $classNames = \array_reduce($classFiles, function (array $classNames, PhpClassFile $classFile) { + return \array_merge( + $classNames, + $classFile->getClasses() + ); + }, []); + + $expected = [ + TestAsset\Anonymous\WithAnonymousClass::class, + ]; + + $this->assertEquals($expected, $classNames); + } } diff --git a/test/TestAsset/Anonymous/WithAnonymousClass.php b/test/TestAsset/Anonymous/WithAnonymousClass.php new file mode 100644 index 0000000..8b754cf --- /dev/null +++ b/test/TestAsset/Anonymous/WithAnonymousClass.php @@ -0,0 +1,24 @@ +anonymous = new class extends \stdClass { + + }; + } +} + diff --git a/test/TestAsset/Anonymous/with-anonymous-class.php b/test/TestAsset/Anonymous/with-anonymous-class.php new file mode 100644 index 0000000..1e0b04e --- /dev/null +++ b/test/TestAsset/Anonymous/with-anonymous-class.php @@ -0,0 +1,13 @@ + Date: Wed, 11 Jan 2017 11:45:04 +0100 Subject: [PATCH 2/2] Fix: Ignore anonymous classes --- src/ClassFileLocator.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ClassFileLocator.php b/src/ClassFileLocator.php index eab1fae..767fee4 100644 --- a/src/ClassFileLocator.php +++ b/src/ClassFileLocator.php @@ -122,6 +122,17 @@ public function accept() if ($i > 0 && is_array($tokens[$i - 1]) && $tokens[$i - 1][0] === T_DOUBLE_COLON) { break; } + + // ignore anonymous classes on PHP 7.1 and greater + if ($i >= 2 + && \is_array($tokens[$i - 1]) + && T_WHITESPACE === $tokens[$i - 1][0] + && \is_array($tokens[$i - 2]) + && T_NEW === $tokens[$i - 2][0] + ) { + break; + } + // no break case T_INTERFACE: // Abstract class, class, interface or trait found