Skip to content

Commit b7f8bc5

Browse files
committed
Add support for concat expressions in HBS files
1 parent 0ed1620 commit b7f8bc5

File tree

4 files changed

+98
-30
lines changed

4 files changed

+98
-30
lines changed

__snapshots__/test.js.snap

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`Test Fixtures concat-expression 1`] = `
4+
"[1/4] 🔍 Finding JS and HBS files...
5+
[2/4] 🔍 Searching for translations keys in JS and HBS files...
6+
[3/4] ⚙️ Checking for unused translations...
7+
[4/4] ⚙️ Checking for missing translations...
8+
9+
👏 No unused translations were found!
10+
11+
👏 No missing translations were found!
12+
"
13+
`;
14+
15+
exports[`Test Fixtures concat-expression 2`] = `Map {}`;
16+
317
exports[`Test Fixtures decorators 1`] = `
418
"[1/4] 🔍 Finding JS and HBS files...
519
[2/4] 🔍 Searching for translations keys in JS and HBS files...
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{{t (concat "prefix" "." "simple")}}
2+
{{t (concat "prefix." (if true "with-if-first" "with-if-second"))}}
3+
{{t (concat "prefix.some-action" (if this.isCompact "-short"))}}
4+
{{t (concat "prefix." (if this.isEditing "edit" "new") ".label")}}
5+
{{t (if true "foo" (concat "prefix." (if this.isEditing "edit" "new") ".nested"))}}
6+
{{t (concat "prefix." this.dynamicKey "not-missing")}}
7+
{{t (concat "prefix." (if true "a1" (if false "b1" (concat "c" (if false "1" "2")))) ".value")}}
8+
{{t (concat "prefix." (if true this.dynamicKey "key-that-should-exist") ".value")}}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
prefix:
2+
simple: Simple concatenation
3+
with-if-first: First condition
4+
with-if-second: Second condition
5+
some-action: Action that can be long
6+
some-action-short: Action
7+
edit:
8+
label: Label on edit branch
9+
nested: Nested concat on edit branch
10+
new:
11+
label: Label on new branch
12+
nested: Nested concat on new branch
13+
a1:
14+
value: Value
15+
b1:
16+
value: Value
17+
c1:
18+
value: Value
19+
c2:
20+
value: Value
21+
key-that-should-exist:
22+
value: value
23+
foo: Foo

index.js

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -228,44 +228,67 @@ async function analyzeHbsFile(content) {
228228
// parse the HBS file
229229
let ast = Glimmer.preprocess(content);
230230

231+
function findKeysInIfExpression(node) {
232+
let keysInFirstParam = findKeysInNode(node.params[1]);
233+
let keysInSecondParam = node.params.length > 2 ? findKeysInNode(node.params[2]) : [''];
234+
235+
return [...keysInFirstParam, ...keysInSecondParam];
236+
}
237+
238+
function findKeysInConcatExpression(node) {
239+
let potentialKeys = [''];
240+
241+
for (let param of node.params) {
242+
let keysInParam = findKeysInNode(param);
243+
244+
if (keysInParam.length === 0) return [];
245+
246+
potentialKeys = potentialKeys.reduce((newPotentialKeys, potentialKey) => {
247+
for (let key of keysInParam) {
248+
newPotentialKeys.push(potentialKey + key);
249+
}
250+
251+
return newPotentialKeys;
252+
}, []);
253+
}
254+
255+
return potentialKeys;
256+
}
257+
258+
function findKeysInNode(node) {
259+
if (!node) return [];
260+
261+
if (node.type === 'StringLiteral') {
262+
return [node.value];
263+
} else if (node.type === 'SubExpression' && node.path.original === 'if') {
264+
return findKeysInIfExpression(node);
265+
} else if (node.type === 'SubExpression' && node.path.original === 'concat') {
266+
return findKeysInConcatExpression(node);
267+
}
268+
269+
return [];
270+
}
271+
272+
function processNode(node) {
273+
if (node.path.type !== 'PathExpression') return;
274+
if (node.path.original !== 't') return;
275+
if (node.params.length === 0) return;
276+
277+
for (let key of findKeysInNode(node.params[0])) {
278+
translationKeys.add(key);
279+
}
280+
}
281+
231282
// find translation keys in the syntax tree
232283
Glimmer.traverse(ast, {
233284
// handle {{t "foo"}} case
234285
MustacheStatement(node) {
235-
if (node.path.type !== 'PathExpression') return;
236-
if (node.path.original !== 't') return;
237-
if (node.params.length === 0) return;
238-
239-
let firstParam = node.params[0];
240-
if (firstParam.type === 'StringLiteral') {
241-
translationKeys.add(firstParam.value);
242-
} else if (firstParam.type === 'SubExpression' && firstParam.path.original === 'if') {
243-
if (firstParam.params[1].type === 'StringLiteral') {
244-
translationKeys.add(firstParam.params[1].value);
245-
}
246-
if (firstParam.params[2].type === 'StringLiteral') {
247-
translationKeys.add(firstParam.params[2].value);
248-
}
249-
}
286+
processNode(node);
250287
},
251288

252289
// handle {{some-component foo=(t "bar")}} case
253290
SubExpression(node) {
254-
if (node.path.type !== 'PathExpression') return;
255-
if (node.path.original !== 't') return;
256-
if (node.params.length === 0) return;
257-
258-
let firstParam = node.params[0];
259-
if (firstParam.type === 'StringLiteral') {
260-
translationKeys.add(firstParam.value);
261-
} else if (firstParam.type === 'SubExpression' && firstParam.path.original === 'if') {
262-
if (firstParam.params[1].type === 'StringLiteral') {
263-
translationKeys.add(firstParam.params[1].value);
264-
}
265-
if (firstParam.params[2].type === 'StringLiteral') {
266-
translationKeys.add(firstParam.params[2].value);
267-
}
268-
}
291+
processNode(node);
269292
},
270293
});
271294

0 commit comments

Comments
 (0)