From 24ebd8f428cf379d0222247a651a32294c565efc Mon Sep 17 00:00:00 2001 From: Kim Biesbjerg Date: Mon, 26 Aug 2019 12:29:52 +0200 Subject: [PATCH] (bugfix) extract strings encapsulated with backticks. Closes #139 --- package.json | 2 +- src/parsers/abstract-ast.parser.ts | 17 +++++++++++------ src/parsers/function.parser.ts | 2 +- src/parsers/service.parser.ts | 6 +++--- tests/parsers/service.parser.spec.ts | 13 +++++++++++++ tsconfig.json | 4 ++-- 6 files changed, 31 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 8229489f..17f12071 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@biesbjerg/ngx-translate-extract", - "version": "3.0.3", + "version": "3.0.4", "description": "Extract strings from projects using ngx-translate", "main": "dist/index.js", "typings": "dist/index.d.ts", diff --git a/src/parsers/abstract-ast.parser.ts b/src/parsers/abstract-ast.parser.ts index 7cfee3d0..c01a1cb8 100644 --- a/src/parsers/abstract-ast.parser.ts +++ b/src/parsers/abstract-ast.parser.ts @@ -4,7 +4,8 @@ import { CallExpression, Node, SyntaxKind, - StringLiteral + StringLiteral, + NoSubstitutionTemplateLiteral } from 'typescript'; export abstract class AbstractAstParser { @@ -24,19 +25,23 @@ export abstract class AbstractAstParser { } const firstArg = callNode.arguments[0]; - return this.findNodes(firstArg, SyntaxKind.StringLiteral) - .map((node: StringLiteral) => node.text); + + return this.findNodes(firstArg, [ + SyntaxKind.StringLiteral, + SyntaxKind.NoSubstitutionTemplateLiteral + ]) + .map((node: StringLiteral | NoSubstitutionTemplateLiteral) => node.text); } /** * Find all child nodes of a kind */ - protected findNodes(node: Node, kind: SyntaxKind): Node[] { + protected findNodes(node: Node, kinds: SyntaxKind[]): Node[] { const childrenNodes: Node[] = node.getChildren(this.sourceFile); - const initialValue: Node[] = node.kind === kind ? [node] : []; + const initialValue: Node[] = kinds.includes(node.kind) ? [node] : []; return childrenNodes.reduce((result: Node[], childNode: Node) => { - return result.concat(this.findNodes(childNode, kind)); + return result.concat(this.findNodes(childNode, kinds)); }, initialValue); } diff --git a/src/parsers/function.parser.ts b/src/parsers/function.parser.ts index e1db7a7d..7b9eed43 100644 --- a/src/parsers/function.parser.ts +++ b/src/parsers/function.parser.ts @@ -38,7 +38,7 @@ export class FunctionParser extends AbstractAstParser implements ParserInterface node = this.sourceFile; } - let callNodes = this.findNodes(node, SyntaxKind.CallExpression) as CallExpression[]; + let callNodes = this.findNodes(node, [SyntaxKind.CallExpression]) as CallExpression[]; callNodes = callNodes .filter(callNode => { // Only call expressions with arguments diff --git a/src/parsers/service.parser.ts b/src/parsers/service.parser.ts index ae5ca43b..99ebd150 100644 --- a/src/parsers/service.parser.ts +++ b/src/parsers/service.parser.ts @@ -89,14 +89,14 @@ export class ServiceParser extends AbstractAstParser implements ParserInterface * Find class nodes */ protected findClassNodes(node: Node): ClassDeclaration[] { - return this.findNodes(node, SyntaxKind.ClassDeclaration) as ClassDeclaration[]; + return this.findNodes(node, [SyntaxKind.ClassDeclaration]) as ClassDeclaration[]; } /** * Find constructor */ protected findConstructorNode(node: ClassDeclaration): ConstructorDeclaration { - const constructorNodes = this.findNodes(node, SyntaxKind.Constructor) as ConstructorDeclaration[]; + const constructorNodes = this.findNodes(node, [SyntaxKind.Constructor]) as ConstructorDeclaration[]; if (constructorNodes) { return constructorNodes[0]; } @@ -106,7 +106,7 @@ export class ServiceParser extends AbstractAstParser implements ParserInterface * Find all calls to TranslateService methods */ protected findCallNodes(node: Node, propertyIdentifier: string): CallExpression[] { - let callNodes = this.findNodes(node, SyntaxKind.CallExpression) as CallExpression[]; + let callNodes = this.findNodes(node, [SyntaxKind.CallExpression]) as CallExpression[]; callNodes = callNodes .filter(callNode => { // Only call expressions with arguments diff --git a/tests/parsers/service.parser.spec.ts b/tests/parsers/service.parser.spec.ts index 35252dae..2c5f27a2 100644 --- a/tests/parsers/service.parser.spec.ts +++ b/tests/parsers/service.parser.spec.ts @@ -122,6 +122,19 @@ describe('ServiceParser', () => { expect(key).to.deep.equal(['Hello', 'World']); }); + it('should extract string arrays encapsulated in backticks', () => { + const contents = ` + @Component({ }) + export class AppComponent { + public constructor(protected _translateService: TranslateService) { } + public test() { + this._translateService.get([\`Hello\`, \`World\`]); + } + `; + const keys = parser.extract(contents, componentFilename).keys(); + expect(keys).to.deep.equal(['Hello', 'World']); + }); + it('should not extract strings in get()/instant()/stream() methods of other services', () => { const contents = ` @Component({ }) diff --git a/tsconfig.json b/tsconfig.json index 6f955341..b9ebab92 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,10 +5,10 @@ "noImplicitAny": true, "removeComments": true, "declaration": true, - "target": "es6", + "target": "es2015", "lib": [ "dom", - "es2015" + "es2018" ], "module": "commonjs", "outDir": "./dist/",