UNPKG

@tscc/tscc

Version:

A typescript transpiler and bundler that wires up tsickle and closure compiler seamlessly

76 lines (75 loc) 3.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * @fileoverview Contains a common logic that is used to typescript transformers that transforms * ts helper (those in tslib) emits. */ const ts = require("typescript"); const transformer_utils_1 = require("./transformer_utils"); class TsHelperTransformer { constructor(tsickleHost, context, sf) { this.tsickleHost = tsickleHost; this.context = context; this.sf = sf; this.factory = this.context.factory; } /** * Determines whether the given node is a tslib helper call. Such a call expression looks similar * to usual `__decorate(...)` function calls, except that the identifier node __decorate has * a hidden emitNode property. This is encoded in `identifierIsEmitHelper` call and this method * uses it. */ isTsGeneratedHelperCall(node) { if (!ts.isCallExpression(node)) return false; const caller = node.expression; if (!ts.isIdentifier(caller)) return false; if (caller.escapedText !== ts.escapeLeadingUnderscores(this.HELPER_NAME)) return false; if (!(0, transformer_utils_1.identifierIsEmitHelper)(caller)) return false; return true; } maybeTsGeneratedHelperCall(node, googReflectImport) { if (!this.isTsGeneratedHelperCall(node)) return; return this.onHelperCall(node, googReflectImport); } transformSourceFile() { const sf = this.sf; // There's nothing to do when tslib was not imported to the module. if (!(0, transformer_utils_1.findImportedVariable)(sf, 'tslib')) return sf; const existingGoogReflectImport = (0, transformer_utils_1.findImportedVariable)(sf, 'goog:goog.reflect') || (0, transformer_utils_1.findGoogRequiredVariable)(sf, 'goog.reflect'); const googReflectImport = existingGoogReflectImport || this.factory.createIdentifier(`tscc_goog_reflect_injected`); let foundTransformedDecorateCall = false; const visitor = (node) => { let transformed = this.maybeTsGeneratedHelperCall(node, googReflectImport); if (transformed) { foundTransformedDecorateCall = true; return transformed; } return ts.visitEachChild(node, visitor, this.context); }; const newSf = visitor(sf); if (!foundTransformedDecorateCall) return newSf; const stmts = this.combineStatements(newSf.statements.slice(), existingGoogReflectImport ? undefined : googReflectImport); return this.factory.updateSourceFile(newSf, ts.setTextRange(this.factory.createNodeArray(stmts), newSf.statements)); } combineStatements(stmts, googReflectImport) { if (!googReflectImport) return stmts; const requireReflect = this.createGoogReflectRequire(googReflectImport); stmts.unshift(requireReflect); return stmts; } createGoogReflectRequire(ident) { const fh = new transformer_utils_1.NodeFactoryHelper(this.factory); return fh.createVariableAssignment(ident, fh.createGoogCall("require", this.factory.createStringLiteral('goog.reflect')), this.tsickleHost.options.target !== ts.ScriptTarget.ES5); } } exports.default = TsHelperTransformer;