From 1ebc5b7ae6264837315cbc5ff48b826db04206a0 Mon Sep 17 00:00:00 2001 From: Steve Rhoades Date: Thu, 15 May 2014 16:59:19 -0700 Subject: [PATCH] Fixes #6274 added proper support for constants --- .../Zend/Code/Generator/ClassGenerator.php | 133 +++++++++++++ .../Code/Generator/ClassGeneratorTest.php | 174 ++++++++++++++++++ 2 files changed, 307 insertions(+) diff --git a/library/Zend/Code/Generator/ClassGenerator.php b/library/Zend/Code/Generator/ClassGenerator.php index e845587466e..7d088e47eab 100644 --- a/library/Zend/Code/Generator/ClassGenerator.php +++ b/library/Zend/Code/Generator/ClassGenerator.php @@ -56,6 +56,11 @@ class ClassGenerator extends AbstractGenerator */ protected $properties = array(); + /** + * @var PropertyGenerator[] Array of properties + */ + protected $constants = array(); + /** * @var MethodGenerator[] Array of methods */ @@ -116,6 +121,12 @@ public static function fromReflection(ClassReflection $classReflection) } $cg->addProperties($properties); + $constants = array(); + foreach ($classReflection->getConstants() as $name => $value) { + $constants[] = array('name' => $name, 'value' => $value); + } + $cg->addConstants($constants); + $methods = array(); foreach ($classReflection->getMethods() as $reflectionMethod) { $className = ($cg->getNamespaceName())? $cg->getNamespaceName() . "\\" . $cg->getName() : $cg->getName(); @@ -421,6 +432,109 @@ public function getImplementedInterfaces() return $this->implementedInterfaces; } + /** + * @param string $constantName + * @return PropertyGenerator|false + */ + public function getConstant($constantName) + { + if(isset($this->constants[$constantName])) { + return $this->constants[$constantName]; + } + + return false; + } + + /** + * @return PropertyGenerator[] + */ + public function getConstants() + { + return $this->constants; + } + + /** + * @param string $constantName + * @return bool + */ + public function hasConstant($constantName) + { + return isset($this->constants[$constantName]); + } + + /** + * Add constant from PropertyGenerator + * + * @param PropertyGenerator $constant + * @throws Exception\InvalidArgumentException + * @return ClassGenerator + */ + public function addConstantFromGenerator(PropertyGenerator $constant) + { + $constantName = $constant->getName(); + + if (isset($this->constants[$constantName])) { + throw new Exception\InvalidArgumentException(sprintf( + 'A constant by name %s already exists in this class.', + $constantName + )); + } else if (false === $constant->isConst()) { + throw new Exception\InvalidArgumentException(sprintf( + 'The value %s is not defined as a constant.', + $constantName + )); + } + + $this->constants[$constantName] = $constant; + return $this; + } + + /** + * Add Constant + * + * @param string $name + * @param string $value + * @throws Exception\InvalidArgumentException + * @return ClassGenerator + */ + public function addConstant($name, $value) + { + if (!is_string($name)) { + throw new Exception\InvalidArgumentException(sprintf( + '%s expects string for name', + __METHOD__ + )); + } + + if (empty($value) || !is_string($value)) { + throw new Exception\InvalidArgumentException(sprintf( + '%s expects value for constant, value must be a string', + __METHOD__ + )); + } + + return $this->addConstantFromGenerator(new PropertyGenerator($name, $value, PropertyGenerator::FLAG_CONSTANT)); + } + + /** + * @param array $constants + * @return ClassGenerator + */ + public function addConstants(array $constants) + { + foreach ($constants as $constant) { + if ($constant instanceof PropertyGenerator) { + $this->addPropertyFromGenerator($constant); + } else { + if (is_array($constant)) { + call_user_func_array(array($this, 'addConstant'), $constant); + } + } + } + + return $this; + } + /** * @param array $properties * @return ClassGenerator @@ -460,6 +574,12 @@ public function addProperty($name, $defaultValue = null, $flags = PropertyGenera )); } + // backwards compatibility + // @todo remove this on next major version + if($flags === PropertyGenerator::FLAG_CONSTANT) { + return $this->addConstant($name, $defaultValue); + } + return $this->addPropertyFromGenerator(new PropertyGenerator($name, $defaultValue, $flags)); } @@ -481,6 +601,12 @@ public function addPropertyFromGenerator(PropertyGenerator $property) )); } + // backwards compatibility + // @todo remove this on next major version + if($property->isConst()) { + return $this->addConstantFromGenerator($property); + } + $this->properties[$propertyName] = $property; return $this; } @@ -726,6 +852,13 @@ public function generate() $output .= self::LINE_FEED . '{' . self::LINE_FEED . self::LINE_FEED; + $constants = $this->getConstants(); + if(!empty($constants)) { + foreach ($constants as $constant) { + $output .= $constant->generate() . self::LINE_FEED . self::LINE_FEED; + } + } + $properties = $this->getProperties(); if (!empty($properties)) { foreach ($properties as $property) { diff --git a/tests/ZendTest/Code/Generator/ClassGeneratorTest.php b/tests/ZendTest/Code/Generator/ClassGeneratorTest.php index 7b896e81fc1..12eb5b351e0 100644 --- a/tests/ZendTest/Code/Generator/ClassGeneratorTest.php +++ b/tests/ZendTest/Code/Generator/ClassGeneratorTest.php @@ -495,6 +495,7 @@ public function methodOne() } /** +<<<<<<< Upstream, based on zf2/master * @group 6253 */ public function testHereDoc() @@ -530,5 +531,178 @@ public function someFunction() CODE; $this->assertEquals($contents, $classGenerator->generate()); +======= + * @group 6274 + */ + public function testCanAddConstant() + { + $classGenerator = new ClassGenerator(); + $classGenerator->setName('My\Class'); + $classGenerator->addConstant('x', 'value'); + + $this->assertTrue($classGenerator->hasConstant('x')); + $constant = $classGenerator->getConstant('x'); + $this->assertTrue($constant instanceof PropertyGenerator); + $this->assertTrue($constant->isConst()); + $this->assertEquals($constant->getDefaultValue()->getValue(), 'value'); + + } + + /** + * @group 6274 + */ + public function testCanAddConstantsWithArrayOfGenerators() + { + $constants = array( + new PropertyGenerator('x', 'value1', PropertyGenerator::FLAG_CONSTANT), + new PropertyGenerator('y', 'value2', PropertyGenerator::FLAG_CONSTANT) + ); + $classGenerator = new ClassGenerator(); + $classGenerator->addConstants($constants); + + $this->assertEquals(count($classGenerator->getConstants()), 2); + $constantX = $classGenerator->getConstant('x'); + $constantY = $classGenerator->getConstant('y'); + + $this->assertEquals($constantX->getDefaultValue()->getValue(), 'value1'); + $this->assertEquals($constantY->getDefaultValue()->getValue(), 'value2'); + } + + /** + * @group 6274 + */ + public function testCanAddConstantsWithArrayOfKeyValues() + { + $constants = array( + array( 'name'=> 'x', 'value' => 'value1'), + array('name' => 'y', 'value' => 'value2') + ); + $classGenerator = new ClassGenerator(); + $classGenerator->addConstants($constants); + + $this->assertEquals(count($classGenerator->getConstants()), 2); + $constantX = $classGenerator->getConstant('x'); + $constantY = $classGenerator->getConstant('y'); + + $this->assertEquals($constantX->getDefaultValue()->getValue(), 'value1'); + $this->assertEquals($constantY->getDefaultValue()->getValue(), 'value2'); + } + + /** + * @group 6274 + */ + public function testAddConstantThrowsExceptionWithInvalidName() + { + $this->setExpectedException('InvalidArgumentException'); + $classGenerator = new ClassGenerator(); + $classGenerator->addConstant(array(), 'value1'); + } + + /** + * @group 6274 + */ + public function testAddConstantThrowsExceptionWithInvalidValue() + { + $this->setExpectedException('InvalidArgumentException'); + $classGenerator = new ClassGenerator(); + $classGenerator->addConstant('x', null); + } + + /** + * @group 6274 + */ + public function testAddConstantThrowsExceptionOnDuplicate() + { + $this->setExpectedException('InvalidArgumentException'); + $classGenerator = new ClassGenerator(); + $classGenerator->addConstant('x', 'value1'); + $classGenerator->addConstant('x', 'value1'); + } + + /** + * @group 6274 + */ + public function testAddPropertyIsBackwardsCompatibleWithConstants() + { + $classGenerator = new ClassGenerator(); + $classGenerator->addProperty('x', 'value1', PropertyGenerator::FLAG_CONSTANT); + + $constantX = $classGenerator->getConstant('x'); + + $this->assertEquals($constantX->getDefaultValue()->getValue(), 'value1'); + } + + /** + * @group 6274 + */ + public function testAddPropertiesIsBackwardsCompatibleWithConstants() + { + $constants = array( + new PropertyGenerator('x', 'value1', PropertyGenerator::FLAG_CONSTANT), + new PropertyGenerator('y', 'value2', PropertyGenerator::FLAG_CONSTANT) + ); + $classGenerator = new ClassGenerator(); + $classGenerator->addProperties($constants); + + $this->assertEquals(count($classGenerator->getConstants()), 2); + $constantX = $classGenerator->getConstant('x'); + $constantY = $classGenerator->getConstant('y'); + + $this->assertEquals($constantX->getDefaultValue()->getValue(), 'value1'); + $this->assertEquals($constantY->getDefaultValue()->getValue(), 'value2'); + } + + /** + * @group 6274 + */ + public function testConstantsAddedFromReflection() + { + $reflector = new ClassReflection('ZendTest\Code\Generator\TestAsset\TestClassWithManyProperties'); + $classGenerator = ClassGenerator::fromReflection($reflector); + + $constant = $classGenerator->getConstant('FOO'); + $this->assertEquals($constant->getDefaultValue()->getValue(), 'foo'); + } + + /** + * @group 6274 + */ + public function testClassCanBeGeneratedWithConstantAndPropertyWithSameName() + { + $reflector = new ClassReflection('ZendTest\Code\Generator\TestAsset\TestSampleSingleClass'); + $classGenerator = ClassGenerator::fromReflection($reflector); + $classGenerator->addProperty('fooProperty', true, PropertyGenerator::FLAG_PUBLIC); + $classGenerator->addConstant('fooProperty', 'duplicate'); + + $contents = <<<'CODE' +namespace ZendTest\Code\Generator\TestAsset; + +/** + * class docblock + */ +class TestSampleSingleClass +{ + + const fooProperty = 'duplicate'; + + public $fooProperty = true; + + /** + * Enter description here... + * + * @return bool + */ + public function someMethod() + { + /* test test */ + } + + +} + +CODE; + + $this->assertEquals($classGenerator->generate(), $contents); +>>>>>>> ffeb9c9 Fixes #6274 added proper support for constants } }