From 33ea86573e0bc3c60fc13dfdb4812a060811086d Mon Sep 17 00:00:00 2001 From: Fred Emmott Date: Mon, 9 Mar 2015 09:37:56 -0700 Subject: [PATCH 1/4] 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 @@ + Date: Mon, 9 Mar 2015 10:02:10 -0700 Subject: [PATCH 2/4] Use HHVM_VERSION instead of HPHP_VERSION --- src/Composer/Autoload/ClassMapGenerator.php | 2 +- tests/Composer/Test/Autoload/ClassMapGeneratorTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 48b6bdfda..5134be80f 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -114,7 +114,7 @@ class ClassMapGenerator { $traits = version_compare(PHP_VERSION, '5.4', '<') ? '' : '|trait'; $enums = ''; - if (defined('HPHP_VERSION') && version_compare(HPHP_VERSION, '3.3', '>=')) { + if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.3', '>=')) { $enums = '|enum'; } diff --git a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php index beaeba420..3f9e18884 100644 --- a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php +++ b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php @@ -74,7 +74,7 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase 'Foo\\CBar' => __DIR__.'/Fixtures/php5.4/traits.php', )); } - if (defined('HPHP_VERSION') && version_compare(HPHP_VERSION, '3.3', '>=')) { + if (defined('HHVM_VERSION') && version_compare(HHVM_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', From bdf51ab16dd5b05e30eb578ab15daf86284b24ff Mon Sep 17 00:00:00 2001 From: Fred Emmott Date: Mon, 9 Mar 2015 10:05:12 -0700 Subject: [PATCH 3/4] Single variable for traits and enums --- src/Composer/Autoload/ClassMapGenerator.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 5134be80f..862e44ba2 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -112,10 +112,9 @@ class ClassMapGenerator */ private static function findClasses($path) { - $traits = version_compare(PHP_VERSION, '5.4', '<') ? '' : '|trait'; - $enums = ''; + $extraTypes = version_compare(PHP_VERSION, '5.4', '<') ? '' : '|trait'; if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.3', '>=')) { - $enums = '|enum'; + $extraTypes .= '|enum'; } try { @@ -133,7 +132,7 @@ class ClassMapGenerator } // return early if there is no chance of matching anything in this file - if (!preg_match('{\b(?:class|interface'.$traits.$enums.')\s}i', $contents)) { + if (!preg_match('{\b(?:class|interface'.$extraTypes.')\s}i', $contents)) { return array(); } @@ -158,7 +157,7 @@ class ClassMapGenerator preg_match_all('{ (?: - \b(?])(?Pclass|interface'.$traits.$enums.') \s+ (?P[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*) + \b(?])(?Pclass|interface'.$extraTypes.') \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); From 23d5e30fbcf7c660f6a4be36e4470d105bf36536 Mon Sep 17 00:00:00 2001 From: Fred Emmott Date: Mon, 9 Mar 2015 11:28:44 -0700 Subject: [PATCH 4/4] Add test for Generics class Already worked, just adding a test. --- tests/Composer/Test/Autoload/ClassMapGeneratorTest.php | 1 + tests/Composer/Test/Autoload/Fixtures/hhvm3.3/Generics.php | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 tests/Composer/Test/Autoload/Fixtures/hhvm3.3/Generics.php diff --git a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php index 3f9e18884..b8efc0c80 100644 --- a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php +++ b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php @@ -78,6 +78,7 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase $data[] = array(__DIR__.'/Fixtures/hhvm3.3', array( 'FooEnum' => __DIR__.'/Fixtures/hhvm3.3/HackEnum.php', 'Foo\BarEnum' => __DIR__.'/Fixtures/hhvm3.3/NamespacedHackEnum.php', + 'GenericsClass' => __DIR__.'/Fixtures/hhvm3.3/Generics.php', )); } diff --git a/tests/Composer/Test/Autoload/Fixtures/hhvm3.3/Generics.php b/tests/Composer/Test/Autoload/Fixtures/hhvm3.3/Generics.php new file mode 100644 index 000000000..e5d1aa12a --- /dev/null +++ b/tests/Composer/Test/Autoload/Fixtures/hhvm3.3/Generics.php @@ -0,0 +1,4 @@ + { +}