From 33ea86573e0bc3c60fc13dfdb4812a060811086d Mon Sep 17 00:00:00 2001 From: Fred Emmott Date: Mon, 9 Mar 2015 09:37:56 -0700 Subject: [PATCH] Add support for using classmap to autoload Hack enums fixes composer/composer#3823 Ran tests with both PHP5.5.9-1ubuntu4.5 and HHVM 3.6. Test fails on HHVM only if I back out the ClassMapGenerator.php change. --- src/Composer/Autoload/ClassMapGenerator.php | 14 ++++++++++++-- .../Test/Autoload/ClassMapGeneratorTest.php | 6 ++++++ .../Test/Autoload/Fixtures/hhvm3.3/HackEnum.php | 6 ++++++ .../Fixtures/hhvm3.3/NamespacedHackEnum.php | 7 +++++++ 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/Composer/Test/Autoload/Fixtures/hhvm3.3/HackEnum.php create mode 100644 tests/Composer/Test/Autoload/Fixtures/hhvm3.3/NamespacedHackEnum.php diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index f8f18fc28..48b6bdfda 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -113,6 +113,10 @@ class ClassMapGenerator private static function findClasses($path) { $traits = version_compare(PHP_VERSION, '5.4', '<') ? '' : '|trait'; + $enums = ''; + if (defined('HPHP_VERSION') && version_compare(HPHP_VERSION, '3.3', '>=')) { + $enums = '|enum'; + } try { $contents = @php_strip_whitespace($path); @@ -129,7 +133,7 @@ class ClassMapGenerator } // return early if there is no chance of matching anything in this file - if (!preg_match('{\b(?:class|interface'.$traits.')\s}i', $contents)) { + if (!preg_match('{\b(?:class|interface'.$traits.$enums.')\s}i', $contents)) { return array(); } @@ -154,7 +158,7 @@ class ClassMapGenerator preg_match_all('{ (?: - \b(?])(?Pclass|interface'.$traits.') \s+ (?P[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*) + \b(?])(?Pclass|interface'.$traits.$enums.') \s+ (?P[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*) | \b(?])(?Pnamespace) (?P\s+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\s*\\\\\s*[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*)? \s*[\{;] ) }ix', $contents, $matches); @@ -170,6 +174,12 @@ class ClassMapGenerator if ($name[0] === ':') { // This is an XHP class, https://github.com/facebook/xhp $name = 'xhp'.substr(str_replace(array('-', ':'), array('_', '__'), $name), 1); + } else if ($matches['type'][$i] === 'enum') { + // In Hack, something like: + // enum Foo: int { HERP = '123'; } + // The regex above captures the colon, which isn't part of + // the class name. + $name = rtrim($name, ':'); } $classes[] = ltrim($namespace . $name, '\\'); } diff --git a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php index 81f99e57b..beaeba420 100644 --- a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php +++ b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php @@ -74,6 +74,12 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase 'Foo\\CBar' => __DIR__.'/Fixtures/php5.4/traits.php', )); } + if (defined('HPHP_VERSION') && version_compare(HPHP_VERSION, '3.3', '>=')) { + $data[] = array(__DIR__.'/Fixtures/hhvm3.3', array( + 'FooEnum' => __DIR__.'/Fixtures/hhvm3.3/HackEnum.php', + 'Foo\BarEnum' => __DIR__.'/Fixtures/hhvm3.3/NamespacedHackEnum.php', + )); + } return $data; } diff --git a/tests/Composer/Test/Autoload/Fixtures/hhvm3.3/HackEnum.php b/tests/Composer/Test/Autoload/Fixtures/hhvm3.3/HackEnum.php new file mode 100644 index 000000000..4b8dbfd40 --- /dev/null +++ b/tests/Composer/Test/Autoload/Fixtures/hhvm3.3/HackEnum.php @@ -0,0 +1,6 @@ +