diff --git a/src/utils/ast-helpers.ts b/src/utils/ast-helpers.ts index 90d18f90..195dae51 100644 --- a/src/utils/ast-helpers.ts +++ b/src/utils/ast-helpers.ts @@ -10,11 +10,13 @@ import { PropertyAccessExpression, EnumDeclaration, StringLiteral, - SourceFile + SourceFile, + TypeReferenceNode, + EnumMember } from 'typescript'; import pkg from 'typescript'; -const { isIdentifier, isPropertyAccessExpression } = pkg; +const { isIdentifier, isPropertyAccessExpression, isMemberName } = pkg; import glob from 'glob'; import fs from 'fs'; @@ -146,25 +148,42 @@ export function getStringsFromExpression(expression: Expression, sourceFile: Sou } if (isBinaryExpression(expression)) { - const [left] = getStringsFromExpression(expression.left, sourceFile); - const [right] = getStringsFromExpression(expression.right, sourceFile); + const left = getStringsFromExpression(expression.left, sourceFile); + const right = getStringsFromExpression(expression.right, sourceFile); - if (expression.operatorToken.kind === SyntaxKind.PlusToken) { - if (typeof left === 'string' && typeof right === 'string') { - return [left + right]; - } + if (left.length + right.length === 0) { + return []; } if (expression.operatorToken.kind === SyntaxKind.BarBarToken) { - const result = []; - if (typeof left === 'string') { - result.push(left); + if (left.length === 0) { + return right; } - if (typeof right === 'string') { - result.push(right); + if (right.length === 0) { + return left; + } + } + + var results = []; + for (var leftValue of left) { + for (var rightValue of right) { + if (expression.operatorToken.kind === SyntaxKind.PlusToken) { + if (typeof leftValue === 'string' && typeof rightValue === 'string') { + results.push(leftValue + rightValue); + } + } else if (expression.operatorToken.kind === SyntaxKind.BarBarToken) { + console.log(leftValue); + console.log(rightValue); + if (typeof leftValue === 'string') { + results.push(leftValue); + } + if (typeof rightValue === 'string') { + results.push(rightValue); + } + } } - return result; } + return results; } if (isConditionalExpression(expression)) { @@ -204,5 +223,22 @@ export function getStringsFromExpression(expression: Expression, sourceFile: Sou return []; } } + if (isMemberName(expression)) { + const [result] = tsquery(sourceFile, `Parameter:has(Identifier[name=${expression.text}]) TypeReference`); + if (!!result) { + if (isIdentifier(result.typeName)) { + const enumObject = findEnumDeclaration(sourceFile, result.typeName.escapedText.toString()); + if (!enumObject) { + return []; + } + return enumObject.members.reduce((result: string[], member: EnumMember) => { + if (member.initializer && isStringLiteralLike(member.initializer)) { + return [...result, member.initializer.text]; + } + return result; + }, []); + } + } + } return []; } diff --git a/tests/parsers/marker.parser.spec.ts b/tests/parsers/marker.parser.spec.ts index 7fba5a92..59e834fa 100644 --- a/tests/parsers/marker.parser.spec.ts +++ b/tests/parsers/marker.parser.spec.ts @@ -85,4 +85,30 @@ describe('MarkerParser', () => { const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal(['string', 'Extract a string value', 'test']); }); + + it('should extract all possible values when a variable is an enum member', () => { + const contents = ` + import { marker } from '@biesbjerg/ngx-translate-extract-marker'; + import { TEST_ENUM } from './tests/utils/enum'; + + export enum DYNAMIC_TRAD { + string1 = 'string1', + string2 = 'string2', + number = 5 + } + + export class AppModule { + + constructor() { + } + + public testFunction(enumVariable: DYNAMIC_TRAD) { + marker(enumVariable) + marker(enumVariable + " test") + } + } + `; + const keys = parser.extract(contents, componentFilename).keys(); + expect(keys).to.deep.equal(['string1', 'string2', 'string1 test', 'string2 test']); + }); });