UNPKG

refactoring

Version:

JavaScript Refactoring Tools

140 lines (104 loc) 4.66 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _esprima = require('esprima'); var _esprima2 = _interopRequireDefault(_esprima); var _estraverse = require('estraverse'); var _estraverse2 = _interopRequireDefault(_estraverse); var _escodegen = require('escodegen'); var _escodegen2 = _interopRequireDefault(_escodegen); var _chance = require('chance'); var _chance2 = _interopRequireDefault(_chance); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var chance = new _chance2.default(); var defaults = { input: '', client: { startCode: function startCode(id) { return 'inst.start(\'' + id + '\')'; }, endCode: function endCode(id) { return 'inst.end(\'' + id + '\')'; } }, escodegenOptions: { format: { indent: { style: ' ' } } } }; var Instrumenter = function () { function Instrumenter(params) { _classCallCheck(this, Instrumenter); params = Object.assign({}, defaults, params); this.input = params.input; this.client = params.client; this.escodegenOptions = params.escodegenOptions; this.ast = null; this.output = ''; this.ast = _esprima2.default.parse(this.input); } _createClass(Instrumenter, [{ key: 'instrument', value: function instrument() { var _this = this; _estraverse2.default.traverse(this.ast, { enter: function enter(node, parent) { var id = chance.guid(), body = null; var clientStartAst = _esprima2.default.parse(typeof _this.client.startCode === 'function' ? _this.client.startCode(id) : _this.client.startCode); var clientEndAst = _esprima2.default.parse(typeof _this.client.endCode === 'function' ? _this.client.endCode(id) : _this.client.endCode); if (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') { body = node.body.body; if (!body) { throw new Error('No body found for function'); } body.unshift(clientStartAst); if (body[body.length - 1].type !== 'ReturnStatement' && body[body.length - 1].type !== 'ThrowStatement') { body.push(clientEndAst); } _estraverse2.default.traverse(node.body, { enter: function enter(node, parent) { var body = null; if (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') { return _estraverse2.default.VisitorOption.Skip; } if (node.type === 'ReturnStatement' || node.type === 'ThrowStatement') { if (parent.type === 'BlockStatement') { body = parent.body; } else if (parent.type === 'IfStatement') { if (parent.consequent.type !== 'BlockStatement') { parent.consequent = { type: 'BlockStatement', body: [parent.consequent] }; } body = parent.consequent.body; } else if (parent.type === 'SwitchCase') { body = parent.consequent; } if (!body) { throw new Error('No body found for return statement parent'); } for (var l = body.length, i = l - 1; i >= 0; i--) { if (body[i].type === 'ReturnStatement' || body[i].type === 'ThrowStatement') { body.splice(i, 0, clientEndAst); } } } } }); } } }); return _escodegen2.default.generate(this.ast, this.escodegenOptions); } }]); return Instrumenter; }(); exports.default = Instrumenter;