DevTools: Add localization concatenation check to presubmit
Add a localization concatenation check to the presubmit script that issues
an error when a disallowed concatenation is found. Concatenation to a
localizable string is only allowed when it's a string that doesn't
contain letters.
* Example (allowed): ls`Status code` + ': '
* Example (disallowed): ls`Status code: ` + statusCode
* Example (disallowed): ls`Status ` + 'code'
I also fixed the current violations.
Bug: 941561
Change-Id: I428a174f00ad4567a280756b13cfb44bc317d75a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1637146
Reviewed-by: Erik Luo <luoe@chromium.org>
Reviewed-by: Joel Einbinder <einbinder@chromium.org>
Commit-Queue: Mandy Chen <mandy.chen@microsoft.com>
Cr-Original-Commit-Position: refs/heads/master@{#666084}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 5ee0394c3f084d01f0c4a4de2f9b5b455c0db40a
diff --git a/scripts/check_localizability.js b/scripts/check_localizability.js
index 30102a7..e55d741 100644
--- a/scripts/check_localizability.js
+++ b/scripts/check_localizability.js
@@ -88,15 +88,30 @@
/**
* Recursively check if there is concatenation to localization call.
- * Concatenation is allowed between localized strings and non-alphabetic strings.
- * It is not allowed between a localized string and a word.
- * Example (allowed): ls`Status Code` + ": "
- * Example (disallowed): ls`Status` + " Code" + ": "
+ * Concatenation is allowed between localized strings and strings that
+ * don't contain letters.
+ * Example (allowed): ls`Status code: ${statusCode}`
+ * Example (allowed): ls`Status code` + ': '
+ * Example (disallowed): ls`Status code: ` + statusCode
+ * Example (disallowed): ls`Status ` + 'code'
*/
function checkConcatenation(parentNode, node, filePath, errors) {
- function isWord(node) {
- return (node.type === esprimaTypes.LITERAL && !!node.value.match(/[a-z]/i));
+ function isConcatenationDisallowed(node) {
+ if (node.type !== esprimaTypes.LITERAL && node.type !== esprimaTypes.TEMP_LITERAL)
+ return true;
+
+ let value;
+ if (node.type === esprimaTypes.LITERAL)
+ value = node.value;
+ else if (node.type === esprimaTypes.TEMP_LITERAL && node.expressions.length === 0)
+ value = node.quasis[0].value.cooked;
+
+ if (!value || typeof value !== 'string')
+ return true;
+
+ return value.match(/[a-z]/i) !== null;
}
+
function isConcatenation(node) {
return (node !== undefined && node.type === esprimaTypes.BI_EXPR && node.operator === '+');
}
@@ -107,11 +122,12 @@
if (isConcatenation(node)) {
const concatenatedNodes = [];
buildConcatenatedNodesList(node, concatenatedNodes);
- const hasLocalizationCall =
- !!concatenatedNodes.find(currentNode => localizationUtils.isLocalizationCall(currentNode));
+ const nonLocalizationCalls = concatenatedNodes.filter(node => !localizationUtils.isLocalizationCall(node));
+ const hasLocalizationCall = nonLocalizationCalls.length !== concatenatedNodes.length;
if (hasLocalizationCall) {
- const hasAlphabeticLiteral = !!concatenatedNodes.find(currentNode => isWord(currentNode));
- if (hasAlphabeticLiteral) {
+ // concatenation with localization call
+ const hasConcatenationViolation = nonLocalizationCalls.some(isConcatenationDisallowed);
+ if (hasConcatenationViolation) {
const code = escodegen.generate(node);
addError(
`${filePath}${