(feat) add support for extracting binary expressions. example: translateService.instant(message || 'text if message is falsey')
This commit is contained in:
@@ -1,65 +1,77 @@
|
|||||||
import * as ts from 'typescript';
|
import {
|
||||||
|
createSourceFile,
|
||||||
|
SourceFile,
|
||||||
|
CallExpression,
|
||||||
|
Node,
|
||||||
|
SyntaxKind,
|
||||||
|
StringLiteral,
|
||||||
|
isStringLiteralLike,
|
||||||
|
isBinaryExpression,
|
||||||
|
isTemplateLiteralToken,
|
||||||
|
isArrayLiteralExpression
|
||||||
|
} from 'typescript';
|
||||||
import { yellow } from 'colorette';
|
import { yellow } from 'colorette';
|
||||||
|
|
||||||
export abstract class AbstractAstParser {
|
export abstract class AbstractAstParser {
|
||||||
|
|
||||||
protected sourceFile: ts.SourceFile;
|
protected sourceFile: SourceFile;
|
||||||
|
|
||||||
protected createSourceFile(path: string, contents: string): ts.SourceFile {
|
protected createSourceFile(path: string, contents: string): SourceFile {
|
||||||
return ts.createSourceFile(path, contents, null, /*setParentNodes */ false);
|
return createSourceFile(path, contents, null, /*setParentNodes */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get strings from function call's first argument
|
* Get strings from function call's first argument
|
||||||
*/
|
*/
|
||||||
protected getCallArgStrings(callNode: ts.CallExpression): string[] {
|
protected getCallArgStrings(callNode: CallExpression): string[] {
|
||||||
if (!callNode.arguments.length) {
|
if (!callNode.arguments.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const firstArg = callNode.arguments[0];
|
const node = callNode.arguments[0];
|
||||||
switch (firstArg.kind) {
|
|
||||||
case ts.SyntaxKind.StringLiteral:
|
if (isStringLiteralLike(node) || isTemplateLiteralToken(node)) {
|
||||||
case ts.SyntaxKind.FirstTemplateToken:
|
return [node.text];
|
||||||
return [(firstArg as ts.StringLiteral).text];
|
|
||||||
case ts.SyntaxKind.ArrayLiteralExpression:
|
|
||||||
return (firstArg as ts.ArrayLiteralExpression).elements
|
|
||||||
.map((element: ts.StringLiteral) => element.text);
|
|
||||||
case ts.SyntaxKind.Identifier:
|
|
||||||
// TODO
|
|
||||||
console.log(yellow('[Line: %d] We do not support values passed to TranslateService'), this.getLine(firstArg));
|
|
||||||
break;
|
|
||||||
case ts.SyntaxKind.BinaryExpression:
|
|
||||||
// TODO
|
|
||||||
console.log(yellow('[Line: %d] We do not support binary expressions (yet)'), this.getLine(firstArg));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log(yellow(`[Line: %d] Unknown argument type: %s`), this.getLine(firstArg), this.syntaxKindToName(firstArg.kind), firstArg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isArrayLiteralExpression(node)) {
|
||||||
|
return node.elements
|
||||||
|
.map((element: StringLiteral) => element.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBinaryExpression(node)) {
|
||||||
|
return [node.right]
|
||||||
|
.filter(childNode => isStringLiteralLike(childNode))
|
||||||
|
.map((childNode: StringLiteral) => childNode.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(yellow(`Unsupported syntax kind in line %d: %s`), this.getLineNumber(node), this.syntaxKindToName(node.kind));
|
||||||
|
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all child nodes of a kind
|
* Find all child nodes of a kind
|
||||||
*/
|
*/
|
||||||
protected findNodes(node: ts.Node, kind: ts.SyntaxKind): ts.Node[] {
|
protected findNodes(node: Node, kind: SyntaxKind): Node[] {
|
||||||
const childrenNodes: ts.Node[] = node.getChildren(this.sourceFile);
|
const childrenNodes: Node[] = node.getChildren(this.sourceFile);
|
||||||
const initialValue: ts.Node[] = node.kind === kind ? [node] : [];
|
const initialValue: Node[] = node.kind === kind ? [node] : [];
|
||||||
|
|
||||||
return childrenNodes.reduce((result: ts.Node[], childNode: ts.Node) => {
|
return childrenNodes.reduce((result: Node[], childNode: Node) => {
|
||||||
return result.concat(this.findNodes(childNode, kind));
|
return result.concat(this.findNodes(childNode, kind));
|
||||||
}, initialValue);
|
}, initialValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getLine(node: ts.Node): number {
|
protected getLineNumber(node: Node): number {
|
||||||
const { line } = this.sourceFile.getLineAndCharacterOfPosition(node.pos);
|
const { line } = this.sourceFile.getLineAndCharacterOfPosition(node.pos);
|
||||||
return line + 1;
|
return line + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected syntaxKindToName(kind: ts.SyntaxKind): string {
|
protected syntaxKindToName(kind: SyntaxKind): string {
|
||||||
return ts.SyntaxKind[kind];
|
return SyntaxKind[kind];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected printAllChildren(sourceFile: ts.SourceFile, node: ts.Node, depth = 0): void {
|
protected printAllChildren(sourceFile: SourceFile, node: Node, depth = 0): void {
|
||||||
console.log(
|
console.log(
|
||||||
new Array(depth + 1).join('----'),
|
new Array(depth + 1).join('----'),
|
||||||
`[${node.kind}]`,
|
`[${node.kind}]`,
|
||||||
|
|||||||
Reference in New Issue
Block a user