Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"nikic/php-parser": "^5.0",
"symfony/finder": "^5.4 || ^6.4 || ^7.0",
"twig/twig": "^2.0 || ^3.0",
"doctrine/annotations": "^1.7 || ^2.0"
"phpstan/phpdoc-parser": "^2.3"
},
"require-dev": {
"symfony/phpunit-bridge": "^5.4 || ^6.4 || ^7.0",
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
bootstrap="./tests/bootstrap.php"
bootstrap="./vendor/autoload.php"
>

<php>
Expand Down
23 changes: 0 additions & 23 deletions src/Annotation/Desc.php

This file was deleted.

19 changes: 0 additions & 19 deletions src/Annotation/Ignore.php

This file was deleted.

38 changes: 0 additions & 38 deletions src/Annotation/Translate.php

This file was deleted.

58 changes: 34 additions & 24 deletions src/Visitor/BaseVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@

namespace Translation\Extractor\Visitor;

use Doctrine\Common\Annotations\DocParser;
use PhpParser\Node;
use PHPStan\PhpDocParser\Ast\ConstExpr\DoctrineConstExprStringNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine\DoctrineTagValueNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\PhpDocParser\Parser\ConstExprParser;
use PHPStan\PhpDocParser\Parser\PhpDocParser;
use PHPStan\PhpDocParser\Parser\TokenIterator;
use PHPStan\PhpDocParser\Parser\TypeParser;
use PHPStan\PhpDocParser\ParserConfig;
use Symfony\Component\Finder\SplFileInfo;
use Translation\Extractor\Annotation\Desc;
use Translation\Extractor\Annotation\Ignore;
use Translation\Extractor\Model\Error;
use Translation\Extractor\Model\SourceCollection;
use Translation\Extractor\Model\SourceLocation;
Expand All @@ -27,7 +32,8 @@
*/
abstract class BaseVisitor implements Visitor
{
private ?DocParser $docParser = null;
protected ?Lexer $lexer = null;
protected ?PhpDocParser $phpDocParser = null;

protected ?SourceCollection $collection = null;
protected SplFileInfo $file;
Expand All @@ -54,9 +60,11 @@ protected function addError(Node $node, string $errorMessage): void
$line = $node->getAttribute('startLine');
}
if (null !== $docComment) {
$context = 'file '.$file.' near line '.$line;
foreach ($this->getDocParser()->parse($docComment->getText(), $context) as $annotation) {
if ($annotation instanceof Ignore) {
$phpDocNode = $this->getPhpDocParser()->parse(
new TokenIterator($this->lexer->tokenize($docComment->getText()))
);
foreach ($phpDocNode->getTags() as $tag) {
if ($tag->name === '@Ignore') {
return;
}
}
Expand All @@ -78,36 +86,38 @@ protected function getLocation(string $text, int $line, ?Node $node = null, arra
{
$file = $this->getAbsoluteFilePath();
if (null !== $node && null !== $docComment = $node->getDocComment()) {
$parserContext = 'file '.$file.' near line '.$line;
foreach ($this->getDocParser()->parse($docComment->getText(), $parserContext) as $annotation) {
if ($annotation instanceof Ignore) {
$phpDocNode = $this->getPhpDocParser()->parse(
new TokenIterator($this->lexer->tokenize($docComment->getText()))
);
foreach ($phpDocNode->getTags() as $tag) {
if ($tag->name === '@Ignore') {
return null;
} elseif ($annotation instanceof Desc) {
$context['desc'] = $annotation->text;
} elseif ($tag->name === '@Desc' && $tag->value instanceof DoctrineTagValueNode) {
if ([] !== $tag->value->annotation->arguments) {
$context['desc'] = DoctrineConstExprStringNode::unescape($tag->value->annotation->arguments[0]->value);
}
}
}
}

return new SourceLocation($text, $file, $line, $context);
}

private function getDocParser(): DocParser
protected function getPhpDocParser(): PhpDocParser
{
if (null === $this->docParser) {
$this->docParser = new DocParser();

$this->docParser->setImports([
'ignore' => Ignore::class,
'desc' => Desc::class,
]);
$this->docParser->setIgnoreNotImportedAnnotations(true);
if (null === $this->phpDocParser) {
$config = new ParserConfig(usedAttributes: []);
$this->lexer = new Lexer($config);
$constExprParser = new ConstExprParser($config);
$typeParser = new TypeParser($config, $constExprParser);
$this->phpDocParser = new PhpDocParser($config, $typeParser, $constExprParser);
}

return $this->docParser;
return $this->phpDocParser;
}

public function setDocParser(DocParser $docParser): void
public function setPhpDocParser(PhpDocParser $phpDocParser): void
{
$this->docParser = $docParser;
$this->phpDocParser = $phpDocParser;
}
}
24 changes: 9 additions & 15 deletions src/Visitor/Php/Symfony/FormTypeChoices.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@

namespace Translation\Extractor\Visitor\Php\Symfony;

use Doctrine\Common\Annotations\DocParser;
use PhpParser\Node;
use PhpParser\NodeVisitor;
use Translation\Extractor\Annotation\Ignore;
use PHPStan\PhpDocParser\Parser\TokenIterator;
use Translation\Extractor\Model\SourceLocation;

/**
Expand Down Expand Up @@ -134,20 +133,15 @@ public function enterNode(Node $node): ?Node

protected function isIgnored(Node $node): bool
{
// because of getDocParser method is private, we have to create a new custom instance
$docParser = new DocParser();
$docParser->setImports([
'ignore' => Ignore::class,
]);
$docParser->setIgnoreNotImportedAnnotations(true);
if (null !== $docComment = $node->getDocComment()) {
foreach ($docParser->parse($docComment->getText()) as $annotation) {
if ($annotation instanceof Ignore) {
return true;
}
}
if (null === $node->getDocComment()) {
return false;
}

return false;
$phpDocNode = $this->getPhpDocParser()->parse(
new TokenIterator($this->lexer->tokenize($node->getDocComment()->getText()))
);
$ignoreTags = $phpDocNode->getTagsByName('@Ignore');

return count($ignoreTags) > 0;
}
}
11 changes: 2 additions & 9 deletions src/Visitor/Php/Symfony/ValidationAnnotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

namespace Translation\Extractor\Visitor\Php\Symfony;

use Doctrine\Common\Annotations\AnnotationException;
use PhpParser\Node;
use PhpParser\NodeVisitor;
use Symfony\Component\Validator\Mapping\ClassMetadata;
Expand Down Expand Up @@ -60,14 +59,8 @@ public function enterNode(Node $node): ?Node
return null;
}

try {
/** @var ClassMetadata $metadata */
$metadata = $this->metadataFactory->getMetadataFor($name);
} catch (AnnotationException $e) {
$this->addError($node, \sprintf('Could not parse class "%s" for annotations. %s', $this->namespace, $e->getMessage()));

return null;
}
/** @var ClassMetadata $metadata */
$metadata = $this->metadataFactory->getMetadataFor($name);

if (!$metadata->hasConstraints() && !\count($metadata->getConstrainedProperties())) {
return null;
Expand Down
40 changes: 19 additions & 21 deletions src/Visitor/Php/TranslateAnnotationVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@

namespace Translation\Extractor\Visitor\Php;

use Doctrine\Common\Annotations\DocParser;
use PhpParser\Comment;
use PhpParser\Node;
use PhpParser\NodeVisitor;
use PHPStan\PhpDocParser\Ast\ConstExpr\DoctrineConstExprStringNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine\DoctrineTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\PhpDocParser\Parser\TokenIterator;
use Translation\Extractor\Annotation\Translate;

/**
Expand All @@ -24,22 +27,6 @@
*/
class TranslateAnnotationVisitor extends BasePHPVisitor implements NodeVisitor
{
protected ?DocParser $translateDocParser = null;

private function getTranslateDocParser(): DocParser
{
if (null === $this->translateDocParser) {
$this->translateDocParser = new DocParser();

$this->translateDocParser->setImports([
'translate' => Translate::class,
]);
$this->translateDocParser->setIgnoreNotImportedAnnotations(true);
}

return $this->translateDocParser;
}

public function enterNode(Node $node): ?Node
{
// look for strings
Expand All @@ -58,10 +45,21 @@ public function enterNode(Node $node): ?Node
return null;
}

foreach ($this->getTranslateDocParser()->parse($comment->getText()) as $annotation) {
// add phrase to dictionary
$this->addLocation($node->value, $node->getAttribute('startLine'), $node, ['domain' => $annotation->getDomain()]);

$phpDocNode = $this->getPhpDocParser()->parse(
new TokenIterator($this->lexer->tokenize($comment->getText()))
);

$translateTags = $phpDocNode->getTagsByName('@Translate');
if ([] !== $translateTags) {
$domain = 'messages';
if ($translateTags[0]->value instanceof DoctrineTagValueNode) {
foreach ($translateTags[0]->value->annotation->arguments as $argument) {
if ('domain' === $argument->key->name) {
$domain = DoctrineConstExprStringNode::unescape($argument->value);
}
}
}
$this->addLocation($node->value, $node->getAttribute('startLine'), $node, ['domain' => $domain]);
break;
}
}
Expand Down
22 changes: 0 additions & 22 deletions tests/bootstrap.php

This file was deleted.

Loading