ngc-webpack
Version:
A wrapper for the @ngtools/webpack with hooks into the compilation process
85 lines • 3.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var interfaces_1 = require("./interfaces");
// instead of adding `semver` package:
function satisfies(tsVersion) {
var version = tsVersion.split('.').map(function (v) { return Number(v); });
return version[0] > 2 || (version[0] === 2 && version[1] >= 5);
}
// Typescript below 2.5.0 needs a workaround.
var visitEachChild = satisfies(ts.version)
? ts.visitEachChild
: visitEachChildWorkaround;
function makeTransform(standardTransform) {
return function (context) {
var transformer = function (sf) {
var ops = standardTransform(sf);
var removeOps = ops
.filter(function (op) { return op.kind === interfaces_1.OPERATION_KIND.Remove; });
var addOps = ops.filter(function (op) { return op.kind === interfaces_1.OPERATION_KIND.Add; });
var replaceOps = ops
.filter(function (op) { return op.kind === interfaces_1.OPERATION_KIND.Replace; });
var visitor = function (node) {
var modified = false;
var modifiedNodes = [node];
// Check if node should be dropped.
if (removeOps.find(function (op) { return op.target === node; })) {
modifiedNodes = [];
modified = true;
}
// Check if node should be replaced (only replaces with first op found).
var replace = replaceOps.find(function (op) { return op.target === node; });
if (replace) {
modifiedNodes = [replace.replacement];
modified = true;
}
// Check if node should be added to.
var add = addOps.filter(function (op) { return op.target === node; });
if (add.length > 0) {
modifiedNodes = add.filter(function (op) { return op.before; }).map((function (op) { return op.before; })).concat(modifiedNodes, add.filter(function (op) { return op.after; }).map((function (op) { return op.after; })));
modified = true;
}
// If we changed anything, return modified nodes without visiting further.
if (modified) {
return modifiedNodes;
}
else {
// Otherwise return node as is and visit children.
return visitEachChild(node, visitor, context);
}
};
// Only visit source files we have ops for.
return ops.length > 0 ? ts.visitNode(sf, visitor) : sf;
};
return transformer;
};
}
exports.makeTransform = makeTransform;
/**
* This is a version of `ts.visitEachChild` that works that calls our version
* of `updateSourceFileNode`, so that typescript doesn't lose type information
* for property decorators.
* See https://github.com/Microsoft/TypeScript/issues/17384 and
* https://github.com/Microsoft/TypeScript/issues/17551, fixed by
* https://github.com/Microsoft/TypeScript/pull/18051 and released on TS 2.5.0.
*
* @param sf
* @param statements
*/
function visitEachChildWorkaround(node, visitor, context) {
if (node.kind === ts.SyntaxKind.SourceFile) {
var sf = node;
var statements = ts.visitLexicalEnvironment(sf.statements, visitor, context);
if (statements === sf.statements) {
return sf;
}
// Note: Need to clone the original file (and not use `ts.updateSourceFileNode`)
// as otherwise TS fails when resolving types for decorators.
var sfClone = ts.getMutableClone(sf);
sfClone.statements = statements;
return sfClone;
}
return ts.visitEachChild(node, visitor, context);
}
//# sourceMappingURL=make_transform.js.map