/** * Parses the given token reader * * @param \vc\Data\Object\Cls $class The class to fill with data * @param \vc\Tokens\Access $access The token access * @return NULL */ public function parseSignature(\vc\Data\Type\Cls $class, \vc\Tokens\Access $access) { $sig = new \vc\Data\Signature($access->peekAtToken()->getLine(), $access->getComment()); // Keep collecting tokens until we find one that differentiates this // signature between a method and a property. This isn't as strict // as it could be, but it's already complex while (TRUE) { $token = $access->peekToRequired(array(Token::T_STATIC, Token::T_PUBLIC, Token::T_PROTECTED, Token::T_PRIVATE, Token::T_ABSTRACT, Token::T_FINAL, Token::T_FUNCTION, Token::T_VAR, Token::T_VARIABLE)); // These tokens denote a definite method if ($token->is(array(Token::T_ABSTRACT, Token::T_FINAL, Token::T_FUNCTION))) { $class->addMethod($this->methods->parseMethod($sig, $access)); return; } else { if ($token->is(array(Token::T_VAR, Token::T_VARIABLE))) { $class->addProperty($this->properties->parseProperty($sig, $access)); return; } else { if ($token->is(array(Token::T_PUBLIC, Token::T_PROTECTED, Token::T_PRIVATE))) { $sig->setVisibility(\vc\Data\Visibility::fromToken($token)); } else { if ($token->is(Token::T_STATIC)) { $sig->setStatic(TRUE); } } } } // By this point, we have already determined that this token isn't // needed downstream, so we can pop it safely $access->popToken(); } }
/** * Parses the given token reader * * @param \vc\Data\Signature $signature The signature to use as a source * @param \vc\Tokens\Access $access The token access * @return \vc\Data\Property */ public function parseProperty(\vc\Data\Signature $signature, \vc\Tokens\Access $access) { $prop = $signature->buildProperty(); // Keep looking for modifier tokens until we reach the variable. // This isn't as strict as it could be about token order, but it greatly // simplifies the method to do it like this. do { $token = $access->findRequired(array(Token::T_STATIC, Token::T_VAR, Token::T_VARIABLE, Token::T_PUBLIC, Token::T_PROTECTED, Token::T_PRIVATE)); if ($token->is(array(Token::T_PUBLIC, Token::T_PROTECTED, Token::T_PRIVATE))) { $prop->setVisibility(\vc\Data\Visibility::fromToken($token)); } else { if ($token->is(Token::T_STATIC)) { $prop->setStatic(TRUE); } } } while (!$token->is(Token::T_VARIABLE)); $prop->setName($token->getContent()); $token = $access->findRequired(array(Token::T_SEMICOLON, Token::T_EQUALS)); // Look for any default value if ($token->is(Token::T_EQUALS)) { $prop->setValue($this->value->parseValue($access)); $access->findRequired(array(Token::T_SEMICOLON)); } return $prop; }
/** * Parses the given token reader * * @param \vc\Data\Signature $signature The base data from which to build * the method * @param \vc\Tokens\Access $access The token stream * @return \vc\Data\Routine\Method */ public function parseMethod(\vc\Data\Signature $signature, \vc\Tokens\Access $access) { $method = $signature->buildMethod(); // Continue iterating until we encounter a Function token while (TRUE) { $token = $access->peekToRequired(array(Token::T_STATIC, Token::T_ABSTRACT, Token::T_FINAL, Token::T_PUBLIC, Token::T_PROTECTED, Token::T_PRIVATE, Token::T_FUNCTION)); // We don't want to consume the function token because the routine // parser looks for it. Break before we get a chance to pop it off // the stream if ($token->is(Token::T_FUNCTION)) { break; } $access->popToken(); if ($token->is(array(Token::T_PUBLIC, Token::T_PROTECTED, Token::T_PRIVATE))) { $method->setVisibility(\vc\Data\Visibility::fromToken($token)); } else { if ($token->is(Token::T_STATIC)) { $method->setStatic(TRUE); } else { if ($token->is(Token::T_ABSTRACT)) { $method->setAbstract(TRUE); } else { if ($token->is(Token::T_FINAL)) { $method->setFinal(TRUE); } } } } } $this->routine->parseRoutine($method, $access); return $method; }
public function testParseProperty_protected() { $access = \vc\Tokens\Access::buildAccess($this->oneTokenReader()->thenAProtected->thenSomeSpace->thenAVariable('$var')->thenASemicolon); $sig = new \vc\Data\Signature(120, new \vc\Data\Comment('Note')); $this->assertEquals(r8(new \vc\Data\Property(120, new \vc\Data\Comment('Note')))->setName('$var')->setVisibility(\vc\Data\Visibility::vProtected()), $this->getPropertyParser()->parseProperty($sig, $access)); $this->assertEndOfTokens($access); }
public function testVisibilityAccess() { $meth = new \vc\Data\Routine\Method(123); $this->assertEnum(\vc\Data\Visibility::vPUBLIC, $meth->getVisibility()); $visibility = \vc\Data\Visibility::vPrivate(); $this->assertSame($meth, $meth->setVisibility($visibility)); $this->assertSame($visibility, $meth->getVisibility()); }
public function testVisibilityAccess() { $prop = new \vc\Data\Property(123); $this->assertEnum(\vc\Data\Visibility::vPUBLIC, $prop->getVisibility()); $visibility = \vc\Data\Visibility::vPrivate(); $this->assertSame($prop, $prop->setVisibility($visibility)); $this->assertSame($visibility, $prop->getVisibility()); }
public function testFromToken() { $this->assertEquals(\vc\Data\Visibility::vPublic(), \vc\Data\Visibility::fromToken(new \vc\Tokens\Token(Token::T_PUBLIC, 'public', 1))); $this->assertEquals(\vc\Data\Visibility::vProtected(), \vc\Data\Visibility::fromToken(new \vc\Tokens\Token(Token::T_PROTECTED, 'protected', 1))); $this->assertEquals(\vc\Data\Visibility::vPrivate(), \vc\Data\Visibility::fromToken(new \vc\Tokens\Token(Token::T_PRIVATE, 'private', 1))); try { \vc\Data\Visibility::fromToken(new \vc\Tokens\Token(Token::T_CLASS, 'class', 1)); $this->fail("An expected exception was not thrown"); } catch (\r8\Exception\Argument $err) { } }
public function testBuildProperty() { $comment = new \vc\Data\Comment(); $sig = new \vc\Data\Signature(123, $comment); $sig->setVisibility(\vc\Data\Visibility::vPrivate()); $sig->setStatic(TRUE); $prop = $sig->buildProperty(); $this->assertSame(123, $prop->getLine()); $this->assertSame($comment, $prop->getComment()); $this->assertTrue($prop->getStatic()); $this->assertEnum(\vc\Data\Visibility::vPRIVATE, $prop->getVisibility()); }
/** * Constructor... * * @param Integer $line The line this property starts on * @param \vc\Data\Comment $comment The comment describing this property */ public function __construct($line, \vc\Data\Comment $comment = NULL) { $this->line = (int) $line; $this->comment = $comment; $this->visibility = \vc\Data\Visibility::vPublic(); }
public function testParseMethod_AbstractPrivateMethod() { $access = \vc\Tokens\Access::buildAccess($this->oneTokenReader()->thenAnAbstract->thenSomeSpace->thenAPrivate->thenSomeSpace->thenAFunction->thenSomeSpace->thenAName('MyFunc')->thenOpenParens->thenCloseParens->thenAnOpenBlock->thenACloseBlock); $sig = new \vc\Data\Signature(123); $this->assertEquals(r8(new \vc\Data\Routine\Method(123))->setName('MyFunc')->setAbstract(TRUE)->setVisibility(\vc\Data\Visibility::vPrivate()), $this->getMethodParser()->parseMethod($sig, $access)); }
/** * Constructor... * * @param Integer $line The line this routine starts on * @param \vc\Data\Comment $comment The comment describing this routine */ public function __construct($line, \vc\Data\Comment $comment = NULL) { parent::__construct($line, $comment); $this->visibility = \vc\Data\Visibility::vPUBLIC(); }
public function testParseSignature_ProtectedProperty() { $this->assertTokenStreamCreatesProperty(new \vc\Data\Comment('Note'), $this->oneTokenReader()->thenAProtected(50)->thenSomeSpace->thenAVariable('$var'), r8(new \vc\Data\Signature(50, new \vc\Data\Comment('Note')))->setVisibility(\vc\Data\Visibility::vProtected())); }