public function parse($comment, $context) { $annotations = ['params' => [], 'returns' => [], 'vars' => []]; $lexer = new DocLexer(); $lexer->setInput($comment); while (true) { $lexer->moveNext(); $lexer->skipUntil(DocLexer::T_AT); if ($lexer->lookahead === null) { break; } if ($a = $this->parseReturnComment($lexer, $context)) { $annotations['returns'][] = $a; } if ($a = $this->parseParamComment($lexer, $context)) { $annotations['params'][] = $a; } if ($a = $this->parseVarComment($lexer, $context)) { $annotations['vars'][] = $a; } } if (count($annotations['returns']) > 1) { throw AnnotationException::semanticalError("Duplicated return: {$context}"); } if (count($annotations['vars']) > 1) { throw AnnotationException::semanticalError("Duplicated var: {$context}"); } return $annotations; }
/** * Parses the docblock and returns its annotation tokens. * * @param string $input The docblock. * @param array $aliases The namespace aliases. * * @return array The list of tokens. */ public function parse($input, array $aliases = array()) { if (0 !== strpos(ltrim($input), '/**')) { return array(); } if (false == ($position = strpos($input, '@'))) { return array(); } if (0 < $position) { $position -= 1; } $input = substr($input, $position); $input = trim($input, '*/ '); $this->aliases = $aliases; $this->lexer->setInput($input); $this->lexer->moveNext(); return $this->getAnnotations(); }
/** * Parses the given docblock string for annotations. * * @param string $input The docblock string to parse. * @param string $context The parsing context. * * @return array Array of annotations. If no annotations are found, an empty array is returned. */ public function parse($input, $context = '') { $pos = $this->findInitialTokenPosition($input); if ($pos === null) { return array(); } $this->context = $context; $this->lexer->setInput(trim(substr($input, $pos), '* /')); $this->lexer->moveNext(); return $this->Annotations(); }
/** * Parses the given docblock string for annotations. * * @param string $input The docblock string to parse. * @param string $context The parsing context. * @return array Array of annotations. If no annotations are found, an empty array is returned. */ public function parse($input, $context = '') { if (false === ($pos = strpos($input, '@'))) { return array(); } // also parse whatever character is before the @ if ($pos > 0) { $pos -= 1; } $this->context = $context; $this->lexer->setInput(trim(substr($input, $pos), '* /')); $this->lexer->moveNext(); return $this->Annotations(); }
public function testMarkerAnnotation() { $lexer = new DocLexer(); $lexer->setInput("@Name"); $this->assertNull($lexer->token); $this->assertNull($lexer->lookahead); $this->assertTrue($lexer->moveNext()); $this->assertNull($lexer->token); $this->assertEquals('@', $lexer->lookahead['value']); $this->assertTrue($lexer->moveNext()); $this->assertEquals('@', $lexer->token['value']); $this->assertEquals('Name', $lexer->lookahead['value']); $this->assertFalse($lexer->moveNext()); }
public function testScannerTokenizesDocBlockWhitInvalidIdentifier() { $lexer = new DocLexer(); $docblock = '@Foo\\3.42'; $tokens = array(array('value' => '@', 'position' => 0, 'type' => DocLexer::T_AT), array('value' => 'Foo', 'position' => 1, 'type' => DocLexer::T_IDENTIFIER), array('value' => '\\', 'position' => 4, 'type' => DocLexer::T_NAMESPACE_SEPARATOR), array('value' => 3.42, 'position' => 5, 'type' => DocLexer::T_FLOAT)); $lexer->setInput($docblock); foreach ($tokens as $expected) { $lexer->moveNext(); $lookahead = $lexer->lookahead; $this->assertEquals($expected['value'], $lookahead['value']); $this->assertEquals($expected['type'], $lookahead['type']); $this->assertEquals($expected['position'], $lookahead['position']); } $this->assertFalse($lexer->moveNext()); }
/** * @group 44 */ public function testRecognizesDoubleQuotesEscapeSequence() { $lexer = new DocLexer(); $docblock = '@Foo("""' . "\n" . '""")'; $tokens = array(array('value' => '@', 'position' => 0, 'type' => DocLexer::T_AT), array('value' => 'Foo', 'position' => 1, 'type' => DocLexer::T_IDENTIFIER), array('value' => '(', 'position' => 4, 'type' => DocLexer::T_OPEN_PARENTHESIS), array('value' => "\"\n\"", 'position' => 5, 'type' => DocLexer::T_STRING), array('value' => ')', 'position' => 12, 'type' => DocLexer::T_CLOSE_PARENTHESIS)); $lexer->setInput($docblock); foreach ($tokens as $expected) { $lexer->moveNext(); $lookahead = $lexer->lookahead; $this->assertEquals($expected['value'], $lookahead['value']); $this->assertEquals($expected['type'], $lookahead['type']); $this->assertEquals($expected['position'], $lookahead['position']); } $this->assertFalse($lexer->moveNext()); }
/** * @group performance */ public function testDocLexerPerformance() { $method = $this->getMethod(); $methodComment = $method->getDocComment(); $classComment = $method->getDeclaringClass()->getDocComment(); $time = microtime(true); for ($i = 0, $c = 500; $i < $c; $i++) { $lexer = new DocLexer(); $lexer->setInput($methodComment); $lexer->setInput($classComment); } $time = microtime(true) - $time; $this->printResults('doc-lexer', $time, $c); }