From 7fa77a33592f6f22a2bdadb07d8917c09f1c7219 Mon Sep 17 00:00:00 2001
From: Pascal Birchler <pascalb@google.com>
Date: Fri, 17 Dec 2021 15:32:23 +0100
Subject: [PATCH] Fix JS string extraction with unsupported argument type

---
 features/makepot.feature   | 12 ++++++++++++
 src/JsFunctionsScanner.php |  7 +++++++
 2 files changed, 19 insertions(+)

diff --git a/features/makepot.feature b/features/makepot.feature
index f5561703..d619c939 100644
--- a/features/makepot.feature
+++ b/features/makepot.feature
@@ -1799,6 +1799,8 @@ Feature: Generate a POT file of a WordPress project
       (0, _i18n._x)( 'babel-i18n._x', 'babel-i18n._x_context', 'foo-plugin' );
 
       eval( "__( 'Hello Eval World', 'foo-plugin' );" );
+
+      __( `This is a ${ bug }`, 'foo-plugin' );
       """
 
     When I run `wp i18n make-pot foo-plugin`
@@ -1908,6 +1910,10 @@ Feature: Generate a POT file of a WordPress project
       """
       msgid "wrong-domain"
       """
+    And the foo-plugin/foo-plugin.pot file should not contain:
+      """
+      msgid "foo-plugin"
+      """
 
   Scenario: Ignores dynamic import in JavaScript file.
     Given an empty foo-plugin directory
@@ -2444,6 +2450,8 @@ Feature: Generate a POT file of a WordPress project
       __( 'wrong-domain', 'wrong-domain' );
 
       __( 'Hello JS' );
+
+      __( `This is a ${ bug }`, 'do-not-import-me' );
       """
 
     When I run `wp i18n make-pot foo-plugin foo-plugin.pot --domain=bar --ignore-domain`
@@ -2477,6 +2485,10 @@ Feature: Generate a POT file of a WordPress project
       """
       msgid "Hello JS"
       """
+    And the foo-plugin.pot file should not contain:
+      """
+      msgid "do-not-import-me"
+      """
 
   Scenario: Associates comments with the right source string
     Given an empty foo-plugin directory
diff --git a/src/JsFunctionsScanner.php b/src/JsFunctionsScanner.php
index 2d35a838..0f464e61 100644
--- a/src/JsFunctionsScanner.php
+++ b/src/JsFunctionsScanner.php
@@ -118,11 +118,13 @@ function ( $node ) use ( &$translations, $options, &$all_comments ) {
 						'Expression' === substr( $argument->getType(), -strlen( 'Expression' ) )
 					) {
 						$args[] = ''; // The value doesn't matter as it's unused.
+						continue;
 					}
 
 					if ( 'Literal' === $argument->getType() ) {
 						/** @var Node\Literal $argument */
 						$args[] = $argument->getValue();
+						continue;
 					}
 
 					if ( 'TemplateLiteral' === $argument->getType() && 0 === count( $argument->getExpressions() ) ) {
@@ -132,7 +134,12 @@ function ( $node ) use ( &$translations, $options, &$all_comments ) {
 						// Since there are no expressions within the TemplateLiteral, there is only one TemplateElement.
 						$parts  = $argument->getParts();
 						$args[] = $parts[0]->getValue();
+						continue;
 					}
+
+					// If we reach this, an unsupported argument type has been encountered.
+					// Do not try to parse this function call at all.
+					return;
 				}
 
 				switch ( $functions[ $callee['name'] ] ) {