From c43f6c0e57c22c9d2a1f6e591243d4018fecfd37 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Wed, 24 Jan 2024 09:55:38 +0100 Subject: [PATCH] [Translation] Fix constant domain resolution in PhpAstExtractor --- .../Translation/Extractor/PhpAstExtractor.php | 5 +++++ .../Translation/Extractor/Visitor/AbstractVisitor.php | 11 +++++++++++ .../Extractor/Visitor/ConstraintVisitor.php | 10 +++++----- .../Extractor/Visitor/TransMethodVisitor.php | 10 +++++----- .../Extractor/Visitor/TranslatableMessageVisitor.php | 10 +++++----- .../Tests/Extractor/PhpAstExtractorTest.php | 3 +++ .../Tests/Fixtures/extractor-ast/translation.html.php | 5 +++++ 7 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/Translation/Extractor/PhpAstExtractor.php b/src/Symfony/Component/Translation/Extractor/PhpAstExtractor.php index 12d93295440d2..06fc77de3c46c 100644 --- a/src/Symfony/Component/Translation/Extractor/PhpAstExtractor.php +++ b/src/Symfony/Component/Translation/Extractor/PhpAstExtractor.php @@ -46,6 +46,11 @@ public function extract(iterable|string $resource, MessageCatalogue $catalogue): { foreach ($this->extractFiles($resource) as $file) { $traverser = new NodeTraverser(); + + // This is needed to resolve namespaces in class methods/constants. + $nameResolver = new NodeVisitor\NameResolver(); + $traverser->addVisitor($nameResolver); + /** @var AbstractVisitor&NodeVisitor $visitor */ foreach ($this->visitors as $visitor) { $visitor->initialize($catalogue, $file, $this->prefix); diff --git a/src/Symfony/Component/Translation/Extractor/Visitor/AbstractVisitor.php b/src/Symfony/Component/Translation/Extractor/Visitor/AbstractVisitor.php index ae0474ac5b54d..c336896169a8b 100644 --- a/src/Symfony/Component/Translation/Extractor/Visitor/AbstractVisitor.php +++ b/src/Symfony/Component/Translation/Extractor/Visitor/AbstractVisitor.php @@ -119,6 +119,17 @@ private function getStringValue(Node $node): ?string return $node->expr->value; } + if ($node instanceof Node\Expr\ClassConstFetch) { + try { + $reflection = new \ReflectionClass($node->class->toString()); + $constant = $reflection->getReflectionConstant($node->name->toString()); + if (false !== $constant && \is_string($constant->getValue())) { + return $constant->getValue(); + } + } catch (\ReflectionException) { + } + } + return null; } } diff --git a/src/Symfony/Component/Translation/Extractor/Visitor/ConstraintVisitor.php b/src/Symfony/Component/Translation/Extractor/Visitor/ConstraintVisitor.php index 31403522fb468..00fb9eedc7314 100644 --- a/src/Symfony/Component/Translation/Extractor/Visitor/ConstraintVisitor.php +++ b/src/Symfony/Component/Translation/Extractor/Visitor/ConstraintVisitor.php @@ -32,6 +32,11 @@ public function beforeTraverse(array $nodes): ?Node } public function enterNode(Node $node): ?Node + { + return null; + } + + public function leaveNode(Node $node): ?Node { if (!$node instanceof Node\Expr\New_ && !$node instanceof Node\Attribute) { return null; @@ -100,11 +105,6 @@ public function enterNode(Node $node): ?Node return null; } - public function leaveNode(Node $node): ?Node - { - return null; - } - public function afterTraverse(array $nodes): ?Node { return null; diff --git a/src/Symfony/Component/Translation/Extractor/Visitor/TransMethodVisitor.php b/src/Symfony/Component/Translation/Extractor/Visitor/TransMethodVisitor.php index 0b537baa24c13..53a6981a2681a 100644 --- a/src/Symfony/Component/Translation/Extractor/Visitor/TransMethodVisitor.php +++ b/src/Symfony/Component/Translation/Extractor/Visitor/TransMethodVisitor.php @@ -25,6 +25,11 @@ public function beforeTraverse(array $nodes): ?Node } public function enterNode(Node $node): ?Node + { + return null; + } + + public function leaveNode(Node $node): ?Node { if (!$node instanceof Node\Expr\MethodCall && !$node instanceof Node\Expr\FuncCall) { return null; @@ -53,11 +58,6 @@ public function enterNode(Node $node): ?Node return null; } - public function leaveNode(Node $node): ?Node - { - return null; - } - public function afterTraverse(array $nodes): ?Node { return null; diff --git a/src/Symfony/Component/Translation/Extractor/Visitor/TranslatableMessageVisitor.php b/src/Symfony/Component/Translation/Extractor/Visitor/TranslatableMessageVisitor.php index 9849fd2b373e9..6bd8bb022306f 100644 --- a/src/Symfony/Component/Translation/Extractor/Visitor/TranslatableMessageVisitor.php +++ b/src/Symfony/Component/Translation/Extractor/Visitor/TranslatableMessageVisitor.php @@ -25,6 +25,11 @@ public function beforeTraverse(array $nodes): ?Node } public function enterNode(Node $node): ?Node + { + return null; + } + + public function leaveNode(Node $node): ?Node { if (!$node instanceof Node\Expr\New_) { return null; @@ -53,11 +58,6 @@ public function enterNode(Node $node): ?Node return null; } - public function leaveNode(Node $node): ?Node - { - return null; - } - public function afterTraverse(array $nodes): ?Node { return null; diff --git a/src/Symfony/Component/Translation/Tests/Extractor/PhpAstExtractorTest.php b/src/Symfony/Component/Translation/Tests/Extractor/PhpAstExtractorTest.php index d808a365ac383..10a144b2c6cd3 100644 --- a/src/Symfony/Component/Translation/Tests/Extractor/PhpAstExtractorTest.php +++ b/src/Symfony/Component/Translation/Tests/Extractor/PhpAstExtractorTest.php @@ -20,6 +20,8 @@ final class PhpAstExtractorTest extends TestCase { + public const OTHER_DOMAIN = 'not_messages'; + /** * @dataProvider resourcesProvider */ @@ -124,6 +126,7 @@ public function testExtraction(iterable|string $resource) 'variable-assignation-inlined-with-named-arguments-in-trans-method' => 'prefixvariable-assignation-inlined-with-named-arguments-in-trans-method', 'mix-named-arguments-without-parameters' => 'prefixmix-named-arguments-without-parameters', 'mix-named-arguments-disordered' => 'prefixmix-named-arguments-disordered', + 'const-domain' => 'prefixconst-domain', ], 'validators' => [ 'message-in-constraint-attribute' => 'prefixmessage-in-constraint-attribute', diff --git a/src/Symfony/Component/Translation/Tests/Fixtures/extractor-ast/translation.html.php b/src/Symfony/Component/Translation/Tests/Fixtures/extractor-ast/translation.html.php index db27b303c5945..68d966bcdd38d 100644 --- a/src/Symfony/Component/Translation/Tests/Fixtures/extractor-ast/translation.html.php +++ b/src/Symfony/Component/Translation/Tests/Fixtures/extractor-ast/translation.html.php @@ -62,3 +62,8 @@ trans('mix-named-arguments-disordered', domain: 'not_messages', parameters: []); ?> trans(...); // should not fail ?> + +trans('const-domain', [], PhpAstExtractorTest::OTHER_DOMAIN); +?>