ts-simple-ast
Version:
TypeScript compiler wrapper for AST navigation and code generation.
99 lines (98 loc) • 4.87 kB
JavaScript
"use strict";
var __values = (this && this.__values)/* istanbul ignore next */ || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
Object.defineProperty(exports, "__esModule", { value: true });
var utils_1 = require("./../../utils");
var StraightReplacementNodeHandler_1 = require("./StraightReplacementNodeHandler");
var NodeHandlerHelper_1 = require("./NodeHandlerHelper");
/**
* Handler for deailing with a parent that is going to have a child replaced.
*/
var DefaultParentHandler = /** @class */ (function () {
function DefaultParentHandler(compilerFactory, opts) {
this.compilerFactory = compilerFactory;
this.straightReplacementNodeHandler = new StraightReplacementNodeHandler_1.StraightReplacementNodeHandler(compilerFactory);
this.helper = new NodeHandlerHelper_1.NodeHandlerHelper(compilerFactory);
this.childCount = opts.childCount;
this.isFirstChild = opts.isFirstChild;
this.replacingNodes = opts.replacingNodes == null ? undefined : opts.replacingNodes.map(function (n) { return n.compilerNode; });
this.customMappings = opts.customMappings;
}
DefaultParentHandler.prototype.handleNode = function (currentNode, newNode) {
var currentNodeChildren = new utils_1.AdvancedIterator(utils_1.ArrayUtils.toIterator(currentNode.getCompilerChildren()));
var newNodeChildren = new utils_1.AdvancedIterator(newNode.getChildrenIterator());
var count = this.childCount;
// handle any custom mappings
this.handleCustomMappings(newNode);
// get the first child
while (!currentNodeChildren.done && !newNodeChildren.done && !this.isFirstChild(currentNodeChildren.peek, newNodeChildren.peek))
this.helper.handleForValues(this.straightReplacementNodeHandler, currentNodeChildren.next(), newNodeChildren.next());
// try replacing any nodes
while (!currentNodeChildren.done && this.tryReplaceNode(currentNodeChildren.peek))
currentNodeChildren.next();
// add or remove the items
if (count > 0) {
while (count > 0) {
newNodeChildren.next();
count--;
}
}
else if (count < 0) {
while (count < 0) {
this.helper.forgetNodeIfNecessary(currentNodeChildren.next());
count++;
}
}
// handle the rest
while (!currentNodeChildren.done)
this.helper.handleForValues(this.straightReplacementNodeHandler, currentNodeChildren.next(), newNodeChildren.next());
// ensure the new children iterator is done too
if (!newNodeChildren.done)
throw new Error("Error replacing tree: Should not have more children left over.");
this.compilerFactory.replaceCompilerNode(currentNode, newNode.compilerNode);
};
DefaultParentHandler.prototype.handleCustomMappings = function (newParentNode) {
if (this.customMappings == null)
return;
var customMappings = this.customMappings(newParentNode);
try {
for (var customMappings_1 = __values(customMappings), customMappings_1_1 = customMappings_1.next(); !customMappings_1_1.done; customMappings_1_1 = customMappings_1.next()) {
var mapping = customMappings_1_1.value;
var currentNode = mapping.currentNode, newNode = mapping.newNode;
var newCompilerNode = newNode.compilerNode;
// forget before replacing so that the node is removed from the cache
newNode.forget();
// now add the new node will be added to the cache
currentNode.global.compilerFactory.replaceCompilerNode(currentNode, newCompilerNode);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (customMappings_1_1 && !customMappings_1_1.done && (_a = customMappings_1.return)) _a.call(customMappings_1);
}
finally { if (e_1) throw e_1.error; }
}
var e_1, _a;
};
DefaultParentHandler.prototype.tryReplaceNode = function (currentCompilerNode) {
if (this.replacingNodes == null || this.replacingNodes.length === 0)
return false;
var index = this.replacingNodes.indexOf(currentCompilerNode);
if (index === -1)
return false;
this.replacingNodes.splice(index, 1);
this.helper.forgetNodeIfNecessary(currentCompilerNode);
return true;
};
return DefaultParentHandler;
}());
exports.DefaultParentHandler = DefaultParentHandler;