Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

ZF2-530 Implement PropertyScanner #2339

Merged
merged 2 commits into from

3 participants

@postalservice14

I've implemented PropertyScanner and added test cases

@postalservice14

@sasezaki Thanks! That totally makes sense. I've implemented the PropertyScanner.

@sasezaki

@postalservice14 Great! This looks good to me.

@weierophinney weierophinney merged commit d556b6f into zendframework:master

1 check passed

Details default The Travis build passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
45 library/Zend/Code/Scanner/ClassScanner.php
@@ -207,6 +207,11 @@ public function getConstants()
return $return;
}
+ /**
+ * Returns a list of property names
+ *
+ * @return array
+ */
public function getPropertyNames()
{
$this->scan();
@@ -223,6 +228,11 @@ public function getPropertyNames()
return $return;
}
+ /**
+ * Returns a list of properties
+ *
+ * @return array
+ */
public function getProperties()
{
$this->scan();
@@ -239,6 +249,41 @@ public function getProperties()
return $return;
}
+ public function getProperty($propertyNameOrInfoIndex)
+ {
+ $this->scan();
+
+ if (is_int($propertyNameOrInfoIndex)) {
+ $info = $this->infos[$propertyNameOrInfoIndex];
+ if ($info['type'] != 'property') {
+ throw new Exception\InvalidArgumentException('Index of info offset is not about a property');
+ }
+ } elseif (is_string($propertyNameOrInfoIndex)) {
+ $propertyFound = false;
+ foreach ($this->infos as $info) {
+ if ($info['type'] === 'property' && $info['name'] === $propertyNameOrInfoIndex) {
+ $propertyFound = true;
+ break;
+ }
+ }
+ if (!$propertyFound) {
+ return false;
+ }
+ } else {
+ throw new Exception\InvalidArgumentException('Invalid property name of info index type. Must be of type int or string');
+ }
+ if (!isset($info)) {
+ return false;
+ }
+ $p = new PropertyScanner(
+ array_slice($this->tokens, $info['tokenStart'], $info['tokenEnd'] - $info['tokenStart'] + 1),
+ $this->nameInformation
+ );
+ $p->setClass($this->name);
+ $p->setScannerClass($this);
+ return $p;
+ }
+
public function getMethodNames()
{
$this->scan();
View
2  library/Zend/Code/Scanner/MethodScanner.php
@@ -84,7 +84,7 @@ public function getDocComment()
/**
* @param Annotation\AnnotationManager $annotationManager
- * @return Annotation\AnnotationCollection
+ * @return AnnotationScanner
*/
public function getAnnotations(Annotation\AnnotationManager $annotationManager)
{
View
284 library/Zend/Code/Scanner/PropertyScanner.php
@@ -1 +1,285 @@
<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Code
+ */
+
+namespace Zend\Code\Scanner;
+
+use Zend\Code\Annotation;
+use Zend\Code\Exception;
+use Zend\Code\NameInformation;
+
+class PropertyScanner implements ScannerInterface
+{
+ /**
+ * @var bool
+ */
+ protected $isScanned = false;
+
+ /**
+ * @var array
+ */
+ protected $tokens;
+
+ /**
+ * @var NameInformation
+ */
+ protected $nameInformation;
+
+ /**
+ * @var string
+ */
+ protected $class;
+
+ /**
+ * @var ClassScanner
+ */
+ protected $scannerClass;
+
+ /**
+ * @var int
+ */
+ protected $lineStart;
+
+ /**
+ * @var bool
+ */
+ protected $isProtected = false;
+
+ /**
+ * @var bool
+ */
+ protected $isPublic = true;
+
+ /**
+ * @var bool
+ */
+ protected $isPrivate = false;
+
+ /**
+ * @var bool
+ */
+ protected $isStatic = false;
+
+ /**
+ * @var string
+ */
+ protected $docComment;
+
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @var string
+ */
+ protected $value;
+
+ /**
+ * Constructor
+ *
+ * @param array $propertyTokens
+ * @param NameInformation $nameInformation
+ */
+ public function __construct(array $propertyTokens, NameInformation $nameInformation = null)
+ {
+ $this->tokens = $propertyTokens;
+ $this->nameInformation = $nameInformation;
+ }
+
+ /**
+ * @param string $class
+ */
+ public function setClass($class)
+ {
+ $this->class = $class;
+ }
+
+ /**
+ * @param ClassScanner $scannerClass
+ */
+ public function setScannerClass(ClassScanner $scannerClass)
+ {
+ $this->scannerClass = $scannerClass;
+ }
+
+ /**
+ * @return ClassScanner
+ */
+ public function getClassScanner()
+ {
+ return $this->scannerClass;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ $this->scan();
+ return $this->name;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isPublic()
+ {
+ $this->scan();
+ return $this->isPublic;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isPrivate()
+ {
+ $this->scan();
+ return $this->isPrivate;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isProtected()
+ {
+ $this->scan();
+ return $this->isProtected;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isStatic()
+ {
+ $this->scan();
+ return $this->isStatic;
+ }
+
+ /**
+ * @return string
+ */
+ public function getValue()
+ {
+ $this->scan();
+ return $this->value;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDocComment()
+ {
+ $this->scan();
+ return $this->docComment;
+ }
+
+ /**
+ * @param Annotation\AnnotationManager $annotationManager
+ * @return AnnotationScanner
+ */
+ public function getAnnotations(Annotation\AnnotationManager $annotationManager)
+ {
+ if (($docComment = $this->getDocComment()) == '') {
+ return false;
+ }
+
+ return new AnnotationScanner($annotationManager, $docComment, $this->nameInformation);
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ $this->scan();
+ return var_export($this, true);
+ }
+
+ /**
+ * Scan tokens
+ *
+ * @throws \Zend\Code\Exception\RuntimeException
+ */
+ protected function scan()
+ {
+ if ($this->isScanned) {
+ return;
+ }
+
+ if (!$this->tokens) {
+ throw new Exception\RuntimeException('No tokens were provided');
+ }
+
+ /**
+ * Variables & Setup
+ */
+ $tokens = &$this->tokens;
+
+ reset($tokens);
+
+ SCANNER_TOP:
+
+ $token = current($tokens);
+
+ if (!is_string($token)) {
+ list($tokenType, $tokenContent, $tokenLine) = $token;
+
+ switch ($tokenType) {
+ case T_DOC_COMMENT:
+ if ($this->docComment === null && $this->name === null) {
+ $this->docComment = $tokenContent;
+ }
+ goto SCANNER_CONTINUE;
+
+ case T_VARIABLE:
+ $this->name = ltrim($tokenContent, '$');
+ goto SCANNER_CONTINUE;
+
+ case T_PUBLIC:
+ // use defaults
+ goto SCANNER_CONTINUE;
+
+ case T_PROTECTED:
+ $this->isProtected = true;
+ $this->isPublic = false;
+ goto SCANNER_CONTINUE;
+
+ case T_PRIVATE:
+ $this->isPrivate = true;
+ $this->isPublic = false;
+ goto SCANNER_CONTINUE;
+
+ case T_STATIC:
+ $this->isStatic = true;
+ goto SCANNER_CONTINUE;
+
+ default:
+ if ($this->name !== null && trim($tokenContent) !== '') {
+ $this->value .= (is_string($token)) ? $token : $tokenContent;
+ if (substr($this->value, 0, 1) === '"' || substr($this->value, 0, 1) === "'") {
+ $this->value = substr($this->value, 1, -1); // Remove quotes
+ }
+ }
+ goto SCANNER_CONTINUE;
+ }
+ }
+
+ SCANNER_CONTINUE:
+
+ if (next($this->tokens) === false) {
+ goto SCANNER_END;
+ }
+ goto SCANNER_TOP;
+
+ SCANNER_END:
+
+ $this->isScanned = true;
+ }
+}
View
15 tests/ZendTest/Code/Scanner/ClassScannerTest.php
@@ -44,7 +44,6 @@ public function testClassScannerHasProperties()
{
$file = new FileScanner(__DIR__ . '/../TestAsset/FooClass.php');
$class = $file->getClass('ZendTest\Code\TestAsset\FooClass');
- $this->assertInternalType('array', $class->getPropertyNames());
$this->assertContains('bar', $class->getPropertyNames());
}
@@ -59,12 +58,22 @@ public function testClassScannerReturnsMethodsWithMethodScanners()
{
$file = new FileScanner(__DIR__ . '/../TestAsset/FooClass.php');
$class = $file->getClass('ZendTest\Code\TestAsset\FooClass');
- $methods = $class->getMethods(true);
+ $methods = $class->getMethods();
foreach ($methods as $method) {
$this->assertInstanceOf('Zend\Code\Scanner\MethodScanner', $method);
}
}
+ public function testClassScannerReturnsPropertiesWithPropertyScanners()
+ {
+ $file = new FileScanner(__DIR__ . '/../TestAsset/FooClass.php');
+ $class = $file->getClass('ZendTest\Code\TestAsset\FooClass');
+ $properties = $class->getProperties();
+ foreach ($properties as $property) {
+ $this->assertInstanceOf('Zend\Code\Scanner\PropertyScanner', $property);
+ }
+ }
+
public function testClassScannerCanScanInterface()
{
$file = new FileScanner(__DIR__ . '/../TestAsset/FooInterface.php');
@@ -77,7 +86,7 @@ public function testClassScannerCanReturnLineNumbers()
$file = new FileScanner(__DIR__ . '/../TestAsset/FooClass.php');
$class = $file->getClass('ZendTest\Code\TestAsset\FooClass');
$this->assertEquals(11, $class->getLineStart());
- $this->assertEquals(23, $class->getLineEnd());
+ $this->assertEquals(31, $class->getLineEnd());
$file = new FileScanner(__DIR__ . '/../TestAsset/BarClass.php');
$class = $file->getClass('ZendTest\Code\TestAsset\BarClass');
View
47 tests/ZendTest/Code/Scanner/PropertyScannerTest.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Code
+ */
+
+namespace ZendTest\Code\Scanner;
+
+use Zend\Code\Scanner\FileScanner;
+use PHPUnit_Framework_TestCase as TestCase;
+
+class PropertyScannerTest extends TestCase
+{
+ public function testPropertyScannerHasPropertyInformation()
+ {
+ $file = new FileScanner(__DIR__ . '/../TestAsset/FooClass.php');
+ $class = $file->getClass('ZendTest\Code\TestAsset\FooClass');
+
+ $property = $class->getProperty('bar');
+ $this->assertEquals('bar', $property->getName());
+ $this->assertEquals('value', $property->getValue());
+ $this->assertFalse($property->isPublic());
+ $this->assertTrue($property->isProtected());
+ $this->assertFalse($property->isPrivate());
+ $this->assertTrue($property->isStatic());
+
+ $property = $class->getProperty('foo');
+ $this->assertEquals('foo', $property->getName());
+ $this->assertEquals('value2', $property->getValue());
+ $this->assertTrue($property->isPublic());
+ $this->assertFalse($property->isProtected());
+ $this->assertFalse($property->isPrivate());
+ $this->assertFalse($property->isStatic());
+
+ $property = $class->getProperty('baz');
+ $this->assertEquals('baz', $property->getName());
+ $this->assertEquals(3, $property->getValue());
+ $this->assertFalse($property->isPublic());
+ $this->assertFalse($property->isProtected());
+ $this->assertTrue($property->isPrivate());
+ $this->assertFalse($property->isStatic());
+ }
+}
View
8 tests/ZendTest/Code/TestAsset/FooClass.php
@@ -14,6 +14,14 @@
const FOO = self::BAR;
protected static $bar = 'value';
+ public $foo = 'value2';
+
+ /**
+ * Test comment
+ *
+ * @var int
+ */
+ private $baz = 3;
final public function fooBarBaz()
{
Something went wrong with that request. Please try again.