(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