Add support for extracting strings from multiple classes per file. Closes #46
This commit is contained in:
		| @@ -8,27 +8,26 @@ export class ServiceParser extends AbstractAstParser implements ParserInterface | |||||||
|  |  | ||||||
| 	protected _sourceFile: ts.SourceFile; | 	protected _sourceFile: ts.SourceFile; | ||||||
|  |  | ||||||
| 	protected _instancePropertyName: any; |  | ||||||
| 	protected _serviceClassName: string = 'TranslateService'; |  | ||||||
| 	protected _serviceMethodNames: string[] = ['get', 'instant']; |  | ||||||
|  |  | ||||||
| 	public extract(contents: string, path?: string): TranslationCollection { | 	public extract(contents: string, path?: string): TranslationCollection { | ||||||
| 		let collection: TranslationCollection = new TranslationCollection(); |  | ||||||
|  |  | ||||||
| 		this._sourceFile = this._createSourceFile(path, contents); | 		this._sourceFile = this._createSourceFile(path, contents); | ||||||
|  |  | ||||||
| 		this._instancePropertyName = this._getInstancePropertyName(); | 		let collection: TranslationCollection = new TranslationCollection(); | ||||||
| 		if (!this._instancePropertyName) { |  | ||||||
| 			return collection; | 		const constructorNodes: ts.ConstructorDeclaration[] = this._findConstructorNodes(); | ||||||
|  | 		constructorNodes.forEach(constructorNode => { | ||||||
|  | 			const propertyName: string = this._getPropertyName(constructorNode); | ||||||
|  | 			if (!propertyName) { | ||||||
|  | 				return; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 		const callNodes = this._findCallNodes(); | 			const callNodes = this._findCallNodes(this._sourceFile, propertyName); | ||||||
| 			callNodes.forEach(callNode => { | 			callNodes.forEach(callNode => { | ||||||
| 				const keys: string[] = this._getCallArgStrings(callNode); | 				const keys: string[] = this._getCallArgStrings(callNode); | ||||||
| 				if (keys && keys.length) { | 				if (keys && keys.length) { | ||||||
| 					collection = collection.addKeys(keys); | 					collection = collection.addKeys(keys); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
| 		return collection; | 		return collection; | ||||||
| 	} | 	} | ||||||
| @@ -37,8 +36,7 @@ export class ServiceParser extends AbstractAstParser implements ParserInterface | |||||||
| 	 * Detect what the TranslateService instance property | 	 * Detect what the TranslateService instance property | ||||||
| 	 * is called by inspecting constructor params | 	 * is called by inspecting constructor params | ||||||
| 	 */ | 	 */ | ||||||
| 	protected _getInstancePropertyName(): string { | 	protected _getPropertyName(constructorNode: ts.ConstructorDeclaration): string { | ||||||
| 		const constructorNode = this._findConstructorNode(); |  | ||||||
| 		if (!constructorNode) { | 		if (!constructorNode) { | ||||||
| 			return null; | 			return null; | ||||||
| 		} | 		} | ||||||
| @@ -60,7 +58,7 @@ export class ServiceParser extends AbstractAstParser implements ParserInterface | |||||||
| 				return false; | 				return false; | ||||||
| 			} | 			} | ||||||
| 			const className: string = parameterType.text; | 			const className: string = parameterType.text; | ||||||
| 			if (className !== this._serviceClassName) { | 			if (className !== 'TranslateService') { | ||||||
| 				return false; | 				return false; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -73,23 +71,19 @@ export class ServiceParser extends AbstractAstParser implements ParserInterface | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Find first constructor | 	 * Find constructor nodes | ||||||
| 	 */ | 	 */ | ||||||
| 	protected _findConstructorNode(): ts.ConstructorDeclaration { | 	protected _findConstructorNodes(): ts.ConstructorDeclaration[] { | ||||||
| 		const constructors = this._findNodes(this._sourceFile, ts.SyntaxKind.Constructor, true) as ts.ConstructorDeclaration[]; | 		const constructors = this._findNodes(this._sourceFile, ts.SyntaxKind.Constructor, true) as ts.ConstructorDeclaration[]; | ||||||
| 		if (constructors.length) { | 		if (constructors.length) { | ||||||
| 			return constructors[0]; | 			return constructors; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Find all calls to TranslateService methods | 	 * Find all calls to TranslateService methods | ||||||
| 	 */ | 	 */ | ||||||
| 	protected _findCallNodes(node?: ts.Node): ts.CallExpression[] { | 	protected _findCallNodes(node: ts.Node, propertyIdentifier: string): ts.CallExpression[] { | ||||||
| 		if (!node) { |  | ||||||
| 			node = this._sourceFile; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		let callNodes = this._findNodes(node, ts.SyntaxKind.CallExpression) as ts.CallExpression[]; | 		let callNodes = this._findNodes(node, ts.SyntaxKind.CallExpression) as ts.CallExpression[]; | ||||||
| 		callNodes = callNodes | 		callNodes = callNodes | ||||||
| 			.filter(callNode => { | 			.filter(callNode => { | ||||||
| @@ -105,7 +99,7 @@ export class ServiceParser extends AbstractAstParser implements ParserInterface | |||||||
| 				if (!propAccess.getFirstToken() || propAccess.getFirstToken().kind !== ts.SyntaxKind.ThisKeyword) { | 				if (!propAccess.getFirstToken() || propAccess.getFirstToken().kind !== ts.SyntaxKind.ThisKeyword) { | ||||||
| 					return false; | 					return false; | ||||||
| 				} | 				} | ||||||
| 				if (propAccess.name.text !== this._instancePropertyName) { | 				if (propAccess.name.text !== propertyIdentifier) { | ||||||
| 					return false; | 					return false; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -113,7 +107,7 @@ export class ServiceParser extends AbstractAstParser implements ParserInterface | |||||||
| 				if (!methodAccess || methodAccess.kind !== ts.SyntaxKind.PropertyAccessExpression) { | 				if (!methodAccess || methodAccess.kind !== ts.SyntaxKind.PropertyAccessExpression) { | ||||||
| 					return false; | 					return false; | ||||||
| 				} | 				} | ||||||
| 				if (!methodAccess.name || this._serviceMethodNames.indexOf(methodAccess.name.text) === -1) { | 				if (!methodAccess.name || (methodAccess.name.text !== 'get' && methodAccess.name.text !== 'instant')) { | ||||||
| 					return false; | 					return false; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -164,4 +164,25 @@ describe('ServiceParser', () => { | |||||||
| 		expect(keys).to.deep.equal([]); | 		expect(keys).to.deep.equal([]); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
|  | 	it('should extract strings from all classes in the file', () => { | ||||||
|  | 		const contents = ` | ||||||
|  | 			import { Injectable } from '@angular/core'; | ||||||
|  | 			import { TranslateService } from '@ngx-translate/core'; | ||||||
|  | 			export class Stuff { | ||||||
|  | 				thing: string; | ||||||
|  | 				constructor(thing: string) { | ||||||
|  | 					this.thing = thing; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			@Injectable() | ||||||
|  | 			export class AuthService { | ||||||
|  | 				constructor(public translate: TranslateService) { | ||||||
|  | 					console.log(this.translate.instant("Hello!")); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		`; | ||||||
|  | 		const keys = parser.extract(contents, componentFilename).keys(); | ||||||
|  | 		expect(keys).to.deep.equal(['Hello!']); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
| }); | }); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user