From 87b44bf85218013eac78ced9c5eeda9d7861b72e Mon Sep 17 00:00:00 2001 From: sanex3339 Date: Tue, 4 Oct 2016 00:41:57 +0300 Subject: [PATCH] StackTraceAnalyzer refactoring --- dist/index.js | 639 ++++++++++-------- src/StackTraceAnalyzer.ts | 148 ---- src/custom-nodes/CustomNodeAppender.ts | 27 +- src/interfaces/IStackTraceData.d.ts | 7 - .../stack-trace-analyzer/ICalleeData.d.ts | 6 + .../ICalleeDataExtractor.d.ts | 5 + .../IStackTraceAnalyzer.d.ts} | 0 .../stack-trace-analyzer/IStackTraceData.d.ts | 5 + .../StackTraceAnalyzer.ts | 110 +++ .../FunctionDeclarationCalleeDataExtractor.ts | 75 ++ .../FunctionExpressionCalleeDataExtractor.ts | 80 +++ src/types/TCalleeDataExtractor.d.ts | 5 + src/types/TNodeObfuscator.d.ts | 2 +- .../StackTraceAnalyzer-spec.ts | 14 +- test/index.spec.ts | 2 +- 15 files changed, 670 insertions(+), 455 deletions(-) delete mode 100644 src/StackTraceAnalyzer.ts delete mode 100644 src/interfaces/IStackTraceData.d.ts create mode 100644 src/interfaces/stack-trace-analyzer/ICalleeData.d.ts create mode 100644 src/interfaces/stack-trace-analyzer/ICalleeDataExtractor.d.ts rename src/interfaces/{IAnalyzer.d.ts => stack-trace-analyzer/IStackTraceAnalyzer.d.ts} (100%) create mode 100644 src/interfaces/stack-trace-analyzer/IStackTraceData.d.ts create mode 100644 src/stack-trace-analyzer/StackTraceAnalyzer.ts create mode 100644 src/stack-trace-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor.ts create mode 100644 src/stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts create mode 100644 src/types/TCalleeDataExtractor.d.ts rename test/{unit-tests => functional-tests/stack-trace-analyzer}/StackTraceAnalyzer-spec.ts (94%) diff --git a/dist/index.js b/dist/index.js index cff14c56..2da09817 100644 --- a/dist/index.js +++ b/dist/index.js @@ -88,7 +88,7 @@ module.exports = /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 79); +/******/ return __webpack_require__(__webpack_require__.s = 80); /******/ }) /************************************************************************/ /******/ ([ @@ -102,7 +102,7 @@ var _createClass = function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var chance_1 = __webpack_require__(73); +var chance_1 = __webpack_require__(75); var JSFuck_1 = __webpack_require__(19); var Utils = function () { @@ -258,7 +258,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons var escodegen = __webpack_require__(11); var esprima = __webpack_require__(22); -var estraverse = __webpack_require__(5); +var estraverse = __webpack_require__(3); var NodeType_1 = __webpack_require__(6); var Nodes_1 = __webpack_require__(2); var Utils_1 = __webpack_require__(0); @@ -533,6 +533,12 @@ exports.Nodes = Nodes; /* 3 */ /***/ function(module, exports) { +module.exports = require("estraverse"); + +/***/ }, +/* 4 */ +/***/ function(module, exports) { + "use strict"; "use strict"; @@ -543,7 +549,7 @@ exports.Nodes = Nodes; var AppendState = exports.AppendState; /***/ }, -/* 4 */ +/* 5 */ /***/ function(module, exports) { "use strict"; @@ -577,12 +583,6 @@ var AbstractCustomNode = function () { exports.AbstractCustomNode = AbstractCustomNode; -/***/ }, -/* 5 */ -/***/ function(module, exports) { - -module.exports = require("estraverse"); - /***/ }, /* 6 */ /***/ function(module, exports, __webpack_require__) { @@ -656,7 +656,7 @@ var _createClass = function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var JavaScriptObfuscatorCLI_1 = __webpack_require__(31); +var JavaScriptObfuscatorCLI_1 = __webpack_require__(30); var JavaScriptObfuscatorInternal_1 = __webpack_require__(25); var JavaScriptObfuscator = function () { @@ -824,7 +824,7 @@ var _createClass = function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var NodeUtils_1 = __webpack_require__(1); -var StackTraceAnalyzer_1 = __webpack_require__(28); +var StackTraceAnalyzer_1 = __webpack_require__(58); var Utils_1 = __webpack_require__(0); var CustomNodeAppender = function () { @@ -838,11 +838,13 @@ var CustomNodeAppender = function () { var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var blockScopeTraceData = new StackTraceAnalyzer_1.StackTraceAnalyzer(blockScopeBody).analyze(); + var targetBlockScopeBody = void 0; if (!blockScopeTraceData.length) { - NodeUtils_1.NodeUtils.prependNode(blockScopeBody, node); - return; + targetBlockScopeBody = blockScopeBody; + } else { + targetBlockScopeBody = CustomNodeAppender.getOptimalBlockScopeBody(blockScopeTraceData, index); } - NodeUtils_1.NodeUtils.prependNode(CustomNodeAppender.getOptimalBlockScope(blockScopeTraceData, index).body, node); + NodeUtils_1.NodeUtils.prependNode(targetBlockScopeBody, node); } }, { key: 'getIndexByThreshold', @@ -858,13 +860,13 @@ var CustomNodeAppender = function () { }); } }, { - key: 'getOptimalBlockScope', - value: function getOptimalBlockScope(blockScopeTraceData, index) { + key: 'getOptimalBlockScopeBody', + value: function getOptimalBlockScopeBody(blockScopeTraceData, index) { var firstCall = blockScopeTraceData[index]; if (firstCall.stackTrace.length) { - return CustomNodeAppender.getOptimalBlockScope(firstCall.stackTrace, 0); + return CustomNodeAppender.getOptimalBlockScopeBody(firstCall.stackTrace, 0); } else { - return firstCall.callee; + return firstCall.callee.body; } } }]); @@ -1185,7 +1187,7 @@ var esprima = __webpack_require__(22); var escodegen = __webpack_require__(11); var ObfuscationResult_1 = __webpack_require__(18); var Obfuscator_1 = __webpack_require__(26); -var Options_1 = __webpack_require__(56); +var Options_1 = __webpack_require__(55); var SourceMapCorrector_1 = __webpack_require__(27); var JavaScriptObfuscatorInternal = function () { @@ -1251,24 +1253,24 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var estraverse = __webpack_require__(5); -var AppendState_1 = __webpack_require__(3); +var estraverse = __webpack_require__(3); +var AppendState_1 = __webpack_require__(4); var NodeType_1 = __webpack_require__(6); -var CatchClauseObfuscator_1 = __webpack_require__(47); -var ConsoleOutputNodesGroup_1 = __webpack_require__(42); -var DebugProtectionNodesGroup_1 = __webpack_require__(43); -var DomainLockNodesGroup_1 = __webpack_require__(44); -var FunctionDeclarationObfuscator_1 = __webpack_require__(48); -var FunctionObfuscator_1 = __webpack_require__(49); -var LiteralObfuscator_1 = __webpack_require__(50); -var MemberExpressionObfuscator_1 = __webpack_require__(51); -var MethodDefinitionObfuscator_1 = __webpack_require__(52); +var CatchClauseObfuscator_1 = __webpack_require__(46); +var ConsoleOutputNodesGroup_1 = __webpack_require__(41); +var DebugProtectionNodesGroup_1 = __webpack_require__(42); +var DomainLockNodesGroup_1 = __webpack_require__(43); +var FunctionDeclarationObfuscator_1 = __webpack_require__(47); +var FunctionObfuscator_1 = __webpack_require__(48); +var LiteralObfuscator_1 = __webpack_require__(49); +var MemberExpressionObfuscator_1 = __webpack_require__(50); +var MethodDefinitionObfuscator_1 = __webpack_require__(51); var Nodes_1 = __webpack_require__(2); var NodeUtils_1 = __webpack_require__(1); -var ObjectExpressionObfuscator_1 = __webpack_require__(53); -var SelfDefendingNodesGroup_1 = __webpack_require__(45); -var UnicodeArrayNodesGroup_1 = __webpack_require__(46); -var VariableDeclarationObfuscator_1 = __webpack_require__(54); +var ObjectExpressionObfuscator_1 = __webpack_require__(52); +var SelfDefendingNodesGroup_1 = __webpack_require__(44); +var UnicodeArrayNodesGroup_1 = __webpack_require__(45); +var VariableDeclarationObfuscator_1 = __webpack_require__(53); var Obfuscator = function () { function Obfuscator(options) { @@ -1409,128 +1411,6 @@ var _createClass = function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var estraverse = __webpack_require__(5); -var Nodes_1 = __webpack_require__(2); -var NodeUtils_1 = __webpack_require__(1); - -var StackTraceAnalyzer = function () { - function StackTraceAnalyzer(blockScopeBody) { - _classCallCheck(this, StackTraceAnalyzer); - - this.stackTraceData = []; - this.blockScopeBody = blockScopeBody; - } - - _createClass(StackTraceAnalyzer, [{ - key: 'analyze', - value: function analyze() { - var _this = this; - - if (this.blockScopeBody.length === 1) { - estraverse.traverse(this.blockScopeBody[0], { - enter: function enter(node) { - if (Nodes_1.Nodes.isBlockStatementNode(node)) { - _this.analyzeRecursive(node.body, _this.stackTraceData); - return estraverse.VisitorOption.Skip; - } - } - }); - } else { - this.analyzeRecursive(this.blockScopeBody, this.stackTraceData); - } - return this.stackTraceData; - } - }, { - key: 'analyzeRecursive', - value: function analyzeRecursive(blockScopeBody, stackTraceData) { - var _this2 = this; - - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - var _loop = function _loop() { - var rootNode = _step.value; - - estraverse.traverse(rootNode, { - enter: function enter(node) { - var calleeNode = null, - name = ''; - if (Nodes_1.Nodes.isCallExpressionNode(node) && rootNode.parentNode === NodeUtils_1.NodeUtils.getBlockScopeOfNode(node)) { - if (Nodes_1.Nodes.isIdentifierNode(node.callee)) { - calleeNode = _this2.getCalleeBlockStatement(NodeUtils_1.NodeUtils.getBlockScopeOfNode(blockScopeBody[0]), node.callee.name); - name = node.callee.name; - } - } - if (!calleeNode) { - return; - } - var data = { - callee: calleeNode, - name: name, - stackTrace: [] - }; - stackTraceData.push(data); - _this2.analyzeRecursive(calleeNode.body, data.stackTrace); - } - }); - }; - - for (var _iterator = blockScopeBody[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - _loop(); - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - } - }, { - key: 'getCalleeBlockStatement', - value: function getCalleeBlockStatement(node, name) { - var calleeBlockStatement = null; - estraverse.traverse(node, { - enter: function enter(node, parentNode) { - if (Nodes_1.Nodes.isFunctionDeclarationNode(node) && node.id.name === name) { - calleeBlockStatement = node.body; - return estraverse.VisitorOption.Break; - } - if (Nodes_1.Nodes.isFunctionExpressionNode(node) && Nodes_1.Nodes.isVariableDeclaratorNode(parentNode) && Nodes_1.Nodes.isIdentifierNode(parentNode.id) && parentNode.id.name === name) { - calleeBlockStatement = node.body; - return estraverse.VisitorOption.Break; - } - } - }); - return calleeBlockStatement; - } - }]); - - return StackTraceAnalyzer; -}(); - -exports.StackTraceAnalyzer = StackTraceAnalyzer; - -/***/ }, -/* 29 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -"use strict"; - -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; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - var Utils_1 = __webpack_require__(0); var UnicodeArray = function () { @@ -1578,7 +1458,7 @@ var UnicodeArray = function () { exports.UnicodeArray = UnicodeArray; /***/ }, -/* 30 */ +/* 29 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1588,8 +1468,8 @@ var _createClass = function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var fs = __webpack_require__(76); -var mkdirp = __webpack_require__(77); +var fs = __webpack_require__(78); +var mkdirp = __webpack_require__(79); var path = __webpack_require__(23); var Utils_1 = __webpack_require__(0); @@ -1670,7 +1550,7 @@ CLIUtils.encoding = 'utf8'; exports.CLIUtils = CLIUtils; /***/ }, -/* 31 */ +/* 30 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1680,11 +1560,11 @@ var _createClass = function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var commander = __webpack_require__(75); +var commander = __webpack_require__(77); var path = __webpack_require__(23); var SourceMapMode_1 = __webpack_require__(12); var DefaultPreset_1 = __webpack_require__(21); -var CLIUtils_1 = __webpack_require__(30); +var CLIUtils_1 = __webpack_require__(29); var JavaScriptObfuscator_1 = __webpack_require__(9); var Utils_1 = __webpack_require__(0); @@ -1803,7 +1683,7 @@ var JavaScriptObfuscatorCLI = function () { exports.JavaScriptObfuscatorCLI = JavaScriptObfuscatorCLI; /***/ }, -/* 32 */ +/* 31 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1817,9 +1697,9 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var AppendState_1 = __webpack_require__(3); -var ConsoleOutputDisableExpressionTemplate_1 = __webpack_require__(60); -var AbstractCustomNode_1 = __webpack_require__(4); +var AppendState_1 = __webpack_require__(4); +var ConsoleOutputDisableExpressionTemplate_1 = __webpack_require__(62); +var AbstractCustomNode_1 = __webpack_require__(5); var CustomNodeAppender_1 = __webpack_require__(15); var NodeUtils_1 = __webpack_require__(1); @@ -1853,7 +1733,7 @@ var ConsoleOutputDisableExpressionNode = function (_AbstractCustomNode_) { exports.ConsoleOutputDisableExpressionNode = ConsoleOutputDisableExpressionNode; /***/ }, -/* 33 */ +/* 32 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1868,9 +1748,9 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } __webpack_require__(8); -var AppendState_1 = __webpack_require__(3); -var DebufProtectionFunctionCallTemplate_1 = __webpack_require__(61); -var AbstractCustomNode_1 = __webpack_require__(4); +var AppendState_1 = __webpack_require__(4); +var DebufProtectionFunctionCallTemplate_1 = __webpack_require__(63); +var AbstractCustomNode_1 = __webpack_require__(5); var NodeUtils_1 = __webpack_require__(1); var DebugProtectionFunctionCallNode = function (_AbstractCustomNode_) { @@ -1906,7 +1786,7 @@ var DebugProtectionFunctionCallNode = function (_AbstractCustomNode_) { exports.DebugProtectionFunctionCallNode = DebugProtectionFunctionCallNode; /***/ }, -/* 34 */ +/* 33 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1921,9 +1801,9 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } __webpack_require__(8); -var AppendState_1 = __webpack_require__(3); -var DebugProtectionFunctionIntervalTemplate_1 = __webpack_require__(62); -var AbstractCustomNode_1 = __webpack_require__(4); +var AppendState_1 = __webpack_require__(4); +var DebugProtectionFunctionIntervalTemplate_1 = __webpack_require__(64); +var AbstractCustomNode_1 = __webpack_require__(5); var NodeUtils_1 = __webpack_require__(1); var DebugProtectionFunctionIntervalNode = function (_AbstractCustomNode_) { @@ -1959,7 +1839,7 @@ var DebugProtectionFunctionIntervalNode = function (_AbstractCustomNode_) { exports.DebugProtectionFunctionIntervalNode = DebugProtectionFunctionIntervalNode; /***/ }, -/* 35 */ +/* 34 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -1974,9 +1854,9 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } __webpack_require__(8); -var AppendState_1 = __webpack_require__(3); -var DebugProtectionFunctionTemplate_1 = __webpack_require__(63); -var AbstractCustomNode_1 = __webpack_require__(4); +var AppendState_1 = __webpack_require__(4); +var DebugProtectionFunctionTemplate_1 = __webpack_require__(65); +var AbstractCustomNode_1 = __webpack_require__(5); var NodeUtils_1 = __webpack_require__(1); var Utils_1 = __webpack_require__(0); @@ -2023,7 +1903,7 @@ var DebugProtectionFunctionNode = function (_AbstractCustomNode_) { exports.DebugProtectionFunctionNode = DebugProtectionFunctionNode; /***/ }, -/* 36 */ +/* 35 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2040,9 +1920,9 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } __webpack_require__(8); -var AppendState_1 = __webpack_require__(3); -var DomainLockNodeTemplate_1 = __webpack_require__(64); -var AbstractCustomNode_1 = __webpack_require__(4); +var AppendState_1 = __webpack_require__(4); +var DomainLockNodeTemplate_1 = __webpack_require__(66); +var AbstractCustomNode_1 = __webpack_require__(5); var CustomNodeAppender_1 = __webpack_require__(15); var NodeUtils_1 = __webpack_require__(1); var Utils_1 = __webpack_require__(0); @@ -2088,7 +1968,7 @@ var DomainLockNode = function (_AbstractCustomNode_) { exports.DomainLockNode = DomainLockNode; /***/ }, -/* 37 */ +/* 36 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2102,10 +1982,10 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var AppendState_1 = __webpack_require__(3); +var AppendState_1 = __webpack_require__(4); var NoCustomNodesPreset_1 = __webpack_require__(17); -var SelfDefendingTemplate_1 = __webpack_require__(65); -var AbstractCustomNode_1 = __webpack_require__(4); +var SelfDefendingTemplate_1 = __webpack_require__(67); +var AbstractCustomNode_1 = __webpack_require__(5); var JavaScriptObfuscator_1 = __webpack_require__(9); var NodeUtils_1 = __webpack_require__(1); var CustomNodeAppender_1 = __webpack_require__(15); @@ -2140,7 +2020,7 @@ var SelfDefendingUnicodeNode = function (_AbstractCustomNode_) { exports.SelfDefendingUnicodeNode = SelfDefendingUnicodeNode; /***/ }, -/* 38 */ +/* 37 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2157,9 +2037,9 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } __webpack_require__(8); -var AppendState_1 = __webpack_require__(3); -var UnicodeArrayCallsWrapperTemplate_1 = __webpack_require__(66); -var AbstractCustomNode_1 = __webpack_require__(4); +var AppendState_1 = __webpack_require__(4); +var UnicodeArrayCallsWrapperTemplate_1 = __webpack_require__(68); +var AbstractCustomNode_1 = __webpack_require__(5); var NodeUtils_1 = __webpack_require__(1); var Utils_1 = __webpack_require__(0); @@ -2214,7 +2094,7 @@ var UnicodeArrayCallsWrapper = function (_AbstractCustomNode_) { exports.UnicodeArrayCallsWrapper = UnicodeArrayCallsWrapper; /***/ }, -/* 39 */ +/* 38 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2231,12 +2111,12 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } __webpack_require__(8); -var AppendState_1 = __webpack_require__(3); +var AppendState_1 = __webpack_require__(4); var NoCustomNodesPreset_1 = __webpack_require__(17); -var AtobTemplate_1 = __webpack_require__(59); -var SelfDefendingTemplate_1 = __webpack_require__(67); -var UnicodeArrayDecodeNodeTemplate_1 = __webpack_require__(68); -var AbstractCustomNode_1 = __webpack_require__(4); +var AtobTemplate_1 = __webpack_require__(61); +var SelfDefendingTemplate_1 = __webpack_require__(69); +var UnicodeArrayDecodeNodeTemplate_1 = __webpack_require__(70); +var AbstractCustomNode_1 = __webpack_require__(5); var JavaScriptObfuscator_1 = __webpack_require__(9); var NodeUtils_1 = __webpack_require__(1); @@ -2295,7 +2175,7 @@ var UnicodeArrayDecodeNode = function (_AbstractCustomNode_) { exports.UnicodeArrayDecodeNode = UnicodeArrayDecodeNode; /***/ }, -/* 40 */ +/* 39 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2312,9 +2192,9 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } __webpack_require__(8); -var AppendState_1 = __webpack_require__(3); -var UnicodeArrayTemplate_1 = __webpack_require__(69); -var AbstractCustomNode_1 = __webpack_require__(4); +var AppendState_1 = __webpack_require__(4); +var UnicodeArrayTemplate_1 = __webpack_require__(71); +var AbstractCustomNode_1 = __webpack_require__(5); var NodeUtils_1 = __webpack_require__(1); var UnicodeArrayNode = function (_AbstractCustomNode_) { @@ -2381,7 +2261,7 @@ UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH = 4; exports.UnicodeArrayNode = UnicodeArrayNode; /***/ }, -/* 41 */ +/* 40 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2398,11 +2278,11 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } __webpack_require__(8); -var AppendState_1 = __webpack_require__(3); +var AppendState_1 = __webpack_require__(4); var NoCustomNodesPreset_1 = __webpack_require__(17); -var SelfDefendingTemplate_1 = __webpack_require__(70); -var UnicodeArrayRotateFunctionTemplate_1 = __webpack_require__(71); -var AbstractCustomNode_1 = __webpack_require__(4); +var SelfDefendingTemplate_1 = __webpack_require__(72); +var UnicodeArrayRotateFunctionTemplate_1 = __webpack_require__(73); +var AbstractCustomNode_1 = __webpack_require__(5); var JavaScriptObfuscator_1 = __webpack_require__(9); var NodeUtils_1 = __webpack_require__(1); var Utils_1 = __webpack_require__(0); @@ -2465,7 +2345,7 @@ var UnicodeArrayRotateFunctionNode = function (_AbstractCustomNode_) { exports.UnicodeArrayRotateFunctionNode = UnicodeArrayRotateFunctionNode; /***/ }, -/* 42 */ +/* 41 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2478,7 +2358,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var AbstractNodesGroup_1 = __webpack_require__(10); -var ConsoleOutputDisableExpressionNode_1 = __webpack_require__(32); +var ConsoleOutputDisableExpressionNode_1 = __webpack_require__(31); var ConsoleOutputNodesGroup = function (_AbstractNodesGroup_) { _inherits(ConsoleOutputNodesGroup, _AbstractNodesGroup_); @@ -2501,7 +2381,7 @@ var ConsoleOutputNodesGroup = function (_AbstractNodesGroup_) { exports.ConsoleOutputNodesGroup = ConsoleOutputNodesGroup; /***/ }, -/* 43 */ +/* 42 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2513,9 +2393,9 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var DebugProtectionFunctionCallNode_1 = __webpack_require__(33); -var DebugProtectionFunctionIntervalNode_1 = __webpack_require__(34); -var DebugProtectionFunctionNode_1 = __webpack_require__(35); +var DebugProtectionFunctionCallNode_1 = __webpack_require__(32); +var DebugProtectionFunctionIntervalNode_1 = __webpack_require__(33); +var DebugProtectionFunctionNode_1 = __webpack_require__(34); var AbstractNodesGroup_1 = __webpack_require__(10); var Utils_1 = __webpack_require__(0); @@ -2545,7 +2425,7 @@ var DebugProtectionNodesGroup = function (_AbstractNodesGroup_) { exports.DebugProtectionNodesGroup = DebugProtectionNodesGroup; /***/ }, -/* 44 */ +/* 43 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2558,7 +2438,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var AbstractNodesGroup_1 = __webpack_require__(10); -var DomainLockNode_1 = __webpack_require__(36); +var DomainLockNode_1 = __webpack_require__(35); var DomainLockNodesGroup = function (_AbstractNodesGroup_) { _inherits(DomainLockNodesGroup, _AbstractNodesGroup_); @@ -2581,7 +2461,7 @@ var DomainLockNodesGroup = function (_AbstractNodesGroup_) { exports.DomainLockNodesGroup = DomainLockNodesGroup; /***/ }, -/* 45 */ +/* 44 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2594,7 +2474,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var AbstractNodesGroup_1 = __webpack_require__(10); -var SelfDefendingUnicodeNode_1 = __webpack_require__(37); +var SelfDefendingUnicodeNode_1 = __webpack_require__(36); var SelfDefendingNodesGroup = function (_AbstractNodesGroup_) { _inherits(SelfDefendingNodesGroup, _AbstractNodesGroup_); @@ -2617,7 +2497,7 @@ var SelfDefendingNodesGroup = function (_AbstractNodesGroup_) { exports.SelfDefendingNodesGroup = SelfDefendingNodesGroup; /***/ }, -/* 46 */ +/* 45 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2630,11 +2510,11 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var AbstractNodesGroup_1 = __webpack_require__(10); -var UnicodeArray_1 = __webpack_require__(29); -var UnicodeArrayCallsWrapper_1 = __webpack_require__(38); -var UnicodeArrayDecodeNode_1 = __webpack_require__(39); -var UnicodeArrayNode_1 = __webpack_require__(40); -var UnicodeArrayRotateFunctionNode_1 = __webpack_require__(41); +var UnicodeArray_1 = __webpack_require__(28); +var UnicodeArrayCallsWrapper_1 = __webpack_require__(37); +var UnicodeArrayDecodeNode_1 = __webpack_require__(38); +var UnicodeArrayNode_1 = __webpack_require__(39); +var UnicodeArrayRotateFunctionNode_1 = __webpack_require__(40); var Utils_1 = __webpack_require__(0); var UnicodeArrayNodesGroup = function (_AbstractNodesGroup_) { @@ -2679,7 +2559,7 @@ var UnicodeArrayNodesGroup = function (_AbstractNodesGroup_) { exports.UnicodeArrayNodesGroup = UnicodeArrayNodesGroup; /***/ }, -/* 47 */ +/* 46 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2693,7 +2573,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var estraverse = __webpack_require__(5); +var estraverse = __webpack_require__(3); var NodeType_1 = __webpack_require__(6); var AbstractNodeObfuscator_1 = __webpack_require__(7); var IdentifierReplacer_1 = __webpack_require__(14); @@ -2750,7 +2630,7 @@ var CatchClauseObfuscator = function (_AbstractNodeObfuscat) { exports.CatchClauseObfuscator = CatchClauseObfuscator; /***/ }, -/* 48 */ +/* 47 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2764,7 +2644,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var estraverse = __webpack_require__(5); +var estraverse = __webpack_require__(3); var NodeType_1 = __webpack_require__(6); var AbstractNodeObfuscator_1 = __webpack_require__(7); var IdentifierReplacer_1 = __webpack_require__(14); @@ -2825,7 +2705,7 @@ var FunctionDeclarationObfuscator = function (_AbstractNodeObfuscat) { exports.FunctionDeclarationObfuscator = FunctionDeclarationObfuscator; /***/ }, -/* 49 */ +/* 48 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2839,7 +2719,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var estraverse = __webpack_require__(5); +var estraverse = __webpack_require__(3); var NodeType_1 = __webpack_require__(6); var AbstractNodeObfuscator_1 = __webpack_require__(7); var IdentifierReplacer_1 = __webpack_require__(14); @@ -2906,7 +2786,7 @@ var FunctionObfuscator = function (_AbstractNodeObfuscat) { exports.FunctionObfuscator = FunctionObfuscator; /***/ }, -/* 50 */ +/* 49 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2924,7 +2804,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function" var escodegen = __webpack_require__(11); var AbstractNodeObfuscator_1 = __webpack_require__(7); -var BooleanLiteralReplacer_1 = __webpack_require__(55); +var BooleanLiteralReplacer_1 = __webpack_require__(54); var Nodes_1 = __webpack_require__(2); var NumberLiteralReplacer_1 = __webpack_require__(20); var StringLiteralReplacer_1 = __webpack_require__(16); @@ -2971,7 +2851,7 @@ var LiteralObfuscator = function (_AbstractNodeObfuscat) { exports.LiteralObfuscator = LiteralObfuscator; /***/ }, -/* 51 */ +/* 50 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -2986,7 +2866,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var escodegen = __webpack_require__(11); -var estraverse = __webpack_require__(5); +var estraverse = __webpack_require__(3); var NodeType_1 = __webpack_require__(6); var AbstractNodeObfuscator_1 = __webpack_require__(7); var Nodes_1 = __webpack_require__(2); @@ -3056,7 +2936,7 @@ var MemberExpressionObfuscator = function (_AbstractNodeObfuscat) { exports.MemberExpressionObfuscator = MemberExpressionObfuscator; /***/ }, -/* 52 */ +/* 51 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3070,7 +2950,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var estraverse = __webpack_require__(5); +var estraverse = __webpack_require__(3); var AbstractNodeObfuscator_1 = __webpack_require__(7); var Nodes_1 = __webpack_require__(2); var Utils_1 = __webpack_require__(0); @@ -3117,7 +2997,7 @@ var MethodDefinitionObfuscator = function (_AbstractNodeObfuscat) { exports.MethodDefinitionObfuscator = MethodDefinitionObfuscator; /***/ }, -/* 53 */ +/* 52 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3132,7 +3012,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var escodegen = __webpack_require__(11); -var estraverse = __webpack_require__(5); +var estraverse = __webpack_require__(3); var NodeType_1 = __webpack_require__(6); var AbstractNodeObfuscator_1 = __webpack_require__(7); var Nodes_1 = __webpack_require__(2); @@ -3203,7 +3083,7 @@ var ObjectExpressionObfuscator = function (_AbstractNodeObfuscat) { exports.ObjectExpressionObfuscator = ObjectExpressionObfuscator; /***/ }, -/* 54 */ +/* 53 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3217,7 +3097,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var estraverse = __webpack_require__(5); +var estraverse = __webpack_require__(3); var NodeType_1 = __webpack_require__(6); var AbstractNodeObfuscator_1 = __webpack_require__(7); var IdentifierReplacer_1 = __webpack_require__(14); @@ -3280,7 +3160,7 @@ var VariableDeclarationObfuscator = function (_AbstractNodeObfuscat) { exports.VariableDeclarationObfuscator = VariableDeclarationObfuscator; /***/ }, -/* 55 */ +/* 54 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3319,7 +3199,7 @@ var BooleanLiteralReplacer = function (_AbstractReplacer_1$A) { exports.BooleanLiteralReplacer = BooleanLiteralReplacer; /***/ }, -/* 56 */ +/* 55 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3340,11 +3220,11 @@ var __decorate = undefined && undefined.__decorate || function (decorators, targ var __metadata = undefined && undefined.__metadata || function (k, v) { if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; -var class_validator_1 = __webpack_require__(74); -var TSourceMapMode_1 = __webpack_require__(72); +var class_validator_1 = __webpack_require__(76); +var TSourceMapMode_1 = __webpack_require__(74); var DefaultPreset_1 = __webpack_require__(21); -var OptionsNormalizer_1 = __webpack_require__(57); -var ValidationErrorsFormatter_1 = __webpack_require__(58); +var OptionsNormalizer_1 = __webpack_require__(56); +var ValidationErrorsFormatter_1 = __webpack_require__(57); var Options = function Options(obfuscatorOptions) { _classCallCheck(this, Options); @@ -3391,7 +3271,7 @@ exports.Options = Options; var _a; /***/ }, -/* 57 */ +/* 56 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3560,7 +3440,7 @@ OptionsNormalizer.normalizerRules = [OptionsNormalizer.domainLockRule, OptionsNo exports.OptionsNormalizer = OptionsNormalizer; /***/ }, -/* 58 */ +/* 57 */ /***/ function(module, exports) { "use strict"; @@ -3626,8 +3506,216 @@ var ValidationErrorsFormatter = function () { exports.ValidationErrorsFormatter = ValidationErrorsFormatter; +/***/ }, +/* 58 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +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; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var estraverse = __webpack_require__(3); +var NodeType_1 = __webpack_require__(6); +var FunctionDeclarationCalleeDataExtractor_1 = __webpack_require__(59); +var FunctionExpressionCalleeDataExtractor_1 = __webpack_require__(60); +var Nodes_1 = __webpack_require__(2); +var NodeUtils_1 = __webpack_require__(1); + +var StackTraceAnalyzer = function () { + function StackTraceAnalyzer(blockScopeBody) { + _classCallCheck(this, StackTraceAnalyzer); + + this.calleeDataExtractors = new Map([[NodeType_1.NodeType.FunctionDeclaration, FunctionDeclarationCalleeDataExtractor_1.FunctionDeclarationCalleeDataExtractor], [NodeType_1.NodeType.FunctionExpression, FunctionExpressionCalleeDataExtractor_1.FunctionExpressionCalleeDataExtractor]]); + this.blockScopeBody = blockScopeBody; + } + + _createClass(StackTraceAnalyzer, [{ + key: 'analyze', + value: function analyze() { + return this.analyzeRecursive(this.blockScopeBody); + } + }, { + key: 'analyzeRecursive', + value: function analyzeRecursive(blockScopeBody) { + var _this = this; + + var stackTraceData = []; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + var _loop = function _loop() { + var rootNode = _step.value; + + estraverse.traverse(rootNode, { + enter: function enter(node) { + if (!Nodes_1.Nodes.isCallExpressionNode(node) || rootNode.parentNode !== NodeUtils_1.NodeUtils.getBlockScopeOfNode(node)) { + return; + } + _this.calleeDataExtractors.forEach(function (calleeDataExtractor) { + var calleeData = new calleeDataExtractor(blockScopeBody, node.callee).extract(); + if (!calleeData) { + return; + } + stackTraceData.push(Object.assign({}, calleeData, { + stackTrace: _this.analyzeRecursive(calleeData.callee.body) + })); + }); + } + }); + }; + + for (var _iterator = blockScopeBody[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + _loop(); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return stackTraceData; + } + }]); + + return StackTraceAnalyzer; +}(); + +exports.StackTraceAnalyzer = StackTraceAnalyzer; + /***/ }, /* 59 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +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; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var estraverse = __webpack_require__(3); +var Nodes_1 = __webpack_require__(2); +var NodeUtils_1 = __webpack_require__(1); + +var FunctionDeclarationCalleeDataExtractor = function () { + function FunctionDeclarationCalleeDataExtractor(blockScopeBody, callee) { + _classCallCheck(this, FunctionDeclarationCalleeDataExtractor); + + this.blockScopeBody = blockScopeBody; + this.callee = callee; + } + + _createClass(FunctionDeclarationCalleeDataExtractor, [{ + key: 'extract', + value: function extract() { + var calleeBlockStatement = null; + if (Nodes_1.Nodes.isIdentifierNode(this.callee)) { + calleeBlockStatement = this.getCalleeBlockStatement(NodeUtils_1.NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), this.callee.name); + } + if (!calleeBlockStatement) { + return null; + } + return { + callee: calleeBlockStatement, + name: this.callee.name + }; + } + }, { + key: 'getCalleeBlockStatement', + value: function getCalleeBlockStatement(node, name) { + var calleeBlockStatement = null; + estraverse.traverse(node, { + enter: function enter(node) { + if (Nodes_1.Nodes.isFunctionDeclarationNode(node) && node.id.name === name) { + calleeBlockStatement = node.body; + return estraverse.VisitorOption.Break; + } + } + }); + return calleeBlockStatement; + } + }]); + + return FunctionDeclarationCalleeDataExtractor; +}(); + +exports.FunctionDeclarationCalleeDataExtractor = FunctionDeclarationCalleeDataExtractor; + +/***/ }, +/* 60 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +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; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var estraverse = __webpack_require__(3); +var Nodes_1 = __webpack_require__(2); +var NodeUtils_1 = __webpack_require__(1); + +var FunctionExpressionCalleeDataExtractor = function () { + function FunctionExpressionCalleeDataExtractor(blockScopeBody, callee) { + _classCallCheck(this, FunctionExpressionCalleeDataExtractor); + + this.blockScopeBody = blockScopeBody; + this.callee = callee; + } + + _createClass(FunctionExpressionCalleeDataExtractor, [{ + key: 'extract', + value: function extract() { + var calleeBlockStatement = null; + if (Nodes_1.Nodes.isIdentifierNode(this.callee)) { + calleeBlockStatement = this.getCalleeBlockStatement(NodeUtils_1.NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), this.callee.name); + } + if (!calleeBlockStatement) { + return null; + } + return { + callee: calleeBlockStatement, + name: this.callee.name + }; + } + }, { + key: 'getCalleeBlockStatement', + value: function getCalleeBlockStatement(node, name) { + var calleeBlockStatement = null; + estraverse.traverse(node, { + enter: function enter(node, parentNode) { + if (Nodes_1.Nodes.isFunctionExpressionNode(node) && Nodes_1.Nodes.isVariableDeclaratorNode(parentNode) && Nodes_1.Nodes.isIdentifierNode(parentNode.id) && parentNode.id.name === name) { + calleeBlockStatement = node.body; + return estraverse.VisitorOption.Break; + } + } + }); + return calleeBlockStatement; + } + }]); + + return FunctionExpressionCalleeDataExtractor; +}(); + +exports.FunctionExpressionCalleeDataExtractor = FunctionExpressionCalleeDataExtractor; + +/***/ }, +/* 61 */ /***/ function(module, exports) { "use strict"; @@ -3639,7 +3727,7 @@ function AtobTemplate() { exports.AtobTemplate = AtobTemplate; /***/ }, -/* 60 */ +/* 62 */ /***/ function(module, exports) { "use strict"; @@ -3651,7 +3739,7 @@ function ConsoleOutputDisableExpressionTemplate() { exports.ConsoleOutputDisableExpressionTemplate = ConsoleOutputDisableExpressionTemplate; /***/ }, -/* 61 */ +/* 63 */ /***/ function(module, exports) { "use strict"; @@ -3663,7 +3751,7 @@ function DebugProtectionFunctionCallTemplate() { exports.DebugProtectionFunctionCallTemplate = DebugProtectionFunctionCallTemplate; /***/ }, -/* 62 */ +/* 64 */ /***/ function(module, exports) { "use strict"; @@ -3675,7 +3763,7 @@ function DebugProtectionFunctionIntervalTemplate() { exports.DebugProtectionFunctionIntervalTemplate = DebugProtectionFunctionIntervalTemplate; /***/ }, -/* 63 */ +/* 65 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3688,7 +3776,7 @@ function DebugProtectionFunctionTemplate() { exports.DebugProtectionFunctionTemplate = DebugProtectionFunctionTemplate; /***/ }, -/* 64 */ +/* 66 */ /***/ function(module, exports) { "use strict"; @@ -3700,7 +3788,7 @@ function DomainLockNodeTemplate() { exports.DomainLockNodeTemplate = DomainLockNodeTemplate; /***/ }, -/* 65 */ +/* 67 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3713,7 +3801,7 @@ function SelfDefendingTemplate() { exports.SelfDefendingTemplate = SelfDefendingTemplate; /***/ }, -/* 66 */ +/* 68 */ /***/ function(module, exports) { "use strict"; @@ -3725,7 +3813,7 @@ function UnicodeArrayCallsWrapperTemplate() { exports.UnicodeArrayCallsWrapperTemplate = UnicodeArrayCallsWrapperTemplate; /***/ }, -/* 67 */ +/* 69 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3738,7 +3826,7 @@ function SelfDefendingTemplate() { exports.SelfDefendingTemplate = SelfDefendingTemplate; /***/ }, -/* 68 */ +/* 70 */ /***/ function(module, exports) { "use strict"; @@ -3750,7 +3838,7 @@ function UnicodeArrayDecodeNodeTemplate() { exports.UnicodeArrayDecodeNodeTemplate = UnicodeArrayDecodeNodeTemplate; /***/ }, -/* 69 */ +/* 71 */ /***/ function(module, exports) { "use strict"; @@ -3762,7 +3850,7 @@ function UnicodeArrayTemplate() { exports.UnicodeArrayTemplate = UnicodeArrayTemplate; /***/ }, -/* 70 */ +/* 72 */ /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -3775,7 +3863,7 @@ function SelfDefendingTemplate() { exports.SelfDefendingTemplate = SelfDefendingTemplate; /***/ }, -/* 71 */ +/* 73 */ /***/ function(module, exports) { "use strict"; @@ -3786,46 +3874,45 @@ function UnicodeArrayRotateFunctionTemplate() { } exports.UnicodeArrayRotateFunctionTemplate = UnicodeArrayRotateFunctionTemplate; -/***/ }, -/* 72 */ -/***/ function(module, exports) { - -"use strict"; -"use strict"; - -/***/ }, -/* 73 */ -/***/ function(module, exports) { - -module.exports = require("chance"); - /***/ }, /* 74 */ /***/ function(module, exports) { -module.exports = require("class-validator"); +"use strict"; +"use strict"; /***/ }, /* 75 */ /***/ function(module, exports) { -module.exports = require("commander"); +module.exports = require("chance"); /***/ }, /* 76 */ /***/ function(module, exports) { -module.exports = require("fs"); +module.exports = require("class-validator"); /***/ }, /* 77 */ /***/ function(module, exports) { +module.exports = require("commander"); + +/***/ }, +/* 78 */ +/***/ function(module, exports) { + +module.exports = require("fs"); + +/***/ }, +/* 79 */ +/***/ function(module, exports) { + module.exports = require("mkdirp"); /***/ }, -/* 78 */, -/* 79 */ +/* 80 */ /***/ function(module, exports, __webpack_require__) { "use strict"; diff --git a/src/StackTraceAnalyzer.ts b/src/StackTraceAnalyzer.ts deleted file mode 100644 index c917ff30..00000000 --- a/src/StackTraceAnalyzer.ts +++ /dev/null @@ -1,148 +0,0 @@ -import * as estraverse from 'estraverse'; -import * as ESTree from 'estree'; - -import { TNodeWithBlockStatement } from './types/TNodeWithBlockStatement'; - -import { IStackTraceData } from './interfaces/IStackTraceData'; -import { IStackTraceAnalyzer } from './interfaces/IAnalyzer'; - -import { Nodes } from './Nodes'; -import { NodeUtils } from './NodeUtils'; - -/** - * This class generates a data with code stack trace functions calls - * - * For example: - * - * function Foo () { - * var baz = function () { - * - * } - * - * baz(); - * } - * - * foo(); - * - * Will generate a structure like: - * - * [ - * { - * callee: FOO_FUNCTION_NODE - * name: 'Foo', - * trace: [ - * { - * callee: BAZ_FUNCTION_NODE, - * name: 'baz, - * trace: [] - * } - * ] - * } - * ] - */ -export class StackTraceAnalyzer implements IStackTraceAnalyzer { - /** - * @type {ESTree.Node[]} - */ - private blockScopeBody: ESTree.Node[]; - - /** - * @type {IStackTraceData[]} - */ - private stackTraceData: IStackTraceData[] = []; - - /** - * @param blockScopeBody - */ - constructor (blockScopeBody: ESTree.Node[]) { - this.blockScopeBody = blockScopeBody; - } - - /** - * @returns {T} - */ - public analyze (): IStackTraceData[] { - if (this.blockScopeBody.length === 1) { - estraverse.traverse(this.blockScopeBody[0], { - enter: (node: ESTree.Node): any => { - if (Nodes.isBlockStatementNode(node)) { - this.analyzeRecursive(node.body, this.stackTraceData); - - return estraverse.VisitorOption.Skip; - } - } - }); - } else { - this.analyzeRecursive(this.blockScopeBody, this.stackTraceData); - } - - return this.stackTraceData; - } - - /** - * @param blockScopeBody - * @param stackTraceData - */ - private analyzeRecursive (blockScopeBody: ESTree.Node[], stackTraceData: IStackTraceData[]): void { - for (let rootNode of blockScopeBody) { - estraverse.traverse(rootNode, { - enter: (node: ESTree.Node): any => { - let calleeNode: TNodeWithBlockStatement|null = null, - name: string = ''; - - if (Nodes.isCallExpressionNode(node) && rootNode.parentNode === NodeUtils.getBlockScopeOfNode(node)) { - if (Nodes.isIdentifierNode(node.callee)) { - calleeNode = this.getCalleeBlockStatement( - NodeUtils.getBlockScopeOfNode(blockScopeBody[0]), - node.callee.name - ); - - name = node.callee.name; - } - } - - if (!calleeNode) { - return; - } - - const data: IStackTraceData = { - callee: calleeNode, - name: name, - stackTrace: [] - }; - - stackTraceData.push(data); - - this.analyzeRecursive(calleeNode.body, data.stackTrace); - } - }); - } - } - - private getCalleeBlockStatement (node: ESTree.Node, name: string): TNodeWithBlockStatement|null { - let calleeBlockStatement: TNodeWithBlockStatement|null = null; - - estraverse.traverse(node, { - enter: (node: ESTree.Node, parentNode: ESTree.Node): any => { - if (Nodes.isFunctionDeclarationNode(node) && node.id.name === name) { - calleeBlockStatement = node.body; - - return estraverse.VisitorOption.Break; - } - - if ( - Nodes.isFunctionExpressionNode(node) && - Nodes.isVariableDeclaratorNode(parentNode) && - Nodes.isIdentifierNode(parentNode.id) && - parentNode.id.name === name - ) { - calleeBlockStatement = node.body; - - return estraverse.VisitorOption.Break; - } - } - }); - - return calleeBlockStatement; - } -} diff --git a/src/custom-nodes/CustomNodeAppender.ts b/src/custom-nodes/CustomNodeAppender.ts index 7f2438ea..ccb4698c 100644 --- a/src/custom-nodes/CustomNodeAppender.ts +++ b/src/custom-nodes/CustomNodeAppender.ts @@ -1,11 +1,9 @@ import * as ESTree from 'estree'; -import { TNodeWithBlockStatement } from '../types/TNodeWithBlockStatement'; - -import { IStackTraceData } from '../interfaces/IStackTraceData'; +import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData'; import { NodeUtils } from '../NodeUtils'; -import { StackTraceAnalyzer } from '../StackTraceAnalyzer'; +import { StackTraceAnalyzer } from '../stack-trace-analyzer/StackTraceAnalyzer'; import { Utils } from '../Utils'; /** @@ -34,16 +32,15 @@ export class CustomNodeAppender { public static appendNode (blockScopeBody: ESTree.Node[], node: ESTree.Node, index: number = 0): void { const blockScopeTraceData: IStackTraceData[] = new StackTraceAnalyzer(blockScopeBody).analyze(); - if (!blockScopeTraceData.length) { - NodeUtils.prependNode(blockScopeBody, node); + let targetBlockScopeBody: ESTree.Node[]; - return; + if (!blockScopeTraceData.length) { + targetBlockScopeBody = blockScopeBody; + } else { + targetBlockScopeBody = CustomNodeAppender.getOptimalBlockScopeBody(blockScopeTraceData, index); } - NodeUtils.prependNode( - CustomNodeAppender.getOptimalBlockScope(blockScopeTraceData, index).body, - node - ); + NodeUtils.prependNode(targetBlockScopeBody, node); } /** @@ -64,15 +61,15 @@ export class CustomNodeAppender { /** * @param blockScopeTraceData * @param index - * @returns {TNodeWithBlockStatement} + * @returns {ESTree.Node[]} */ - private static getOptimalBlockScope (blockScopeTraceData: IStackTraceData[], index: number): TNodeWithBlockStatement { + private static getOptimalBlockScopeBody (blockScopeTraceData: IStackTraceData[], index: number): ESTree.Node[] { const firstCall: IStackTraceData = blockScopeTraceData[index]; if (firstCall.stackTrace.length) { - return CustomNodeAppender.getOptimalBlockScope(firstCall.stackTrace, 0); + return CustomNodeAppender.getOptimalBlockScopeBody(firstCall.stackTrace, 0); } else { - return firstCall.callee; + return firstCall.callee.body; } } } diff --git a/src/interfaces/IStackTraceData.d.ts b/src/interfaces/IStackTraceData.d.ts deleted file mode 100644 index e39c58e9..00000000 --- a/src/interfaces/IStackTraceData.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TNodeWithBlockStatement } from '../types/TNodeWithBlockStatement'; - -export interface IStackTraceData { - callee: TNodeWithBlockStatement; - name: string; - stackTrace: IStackTraceData[]; -} diff --git a/src/interfaces/stack-trace-analyzer/ICalleeData.d.ts b/src/interfaces/stack-trace-analyzer/ICalleeData.d.ts new file mode 100644 index 00000000..cf42d2df --- /dev/null +++ b/src/interfaces/stack-trace-analyzer/ICalleeData.d.ts @@ -0,0 +1,6 @@ +import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; + +export interface ICalleeData { + callee: TNodeWithBlockStatement; + name: string; +} diff --git a/src/interfaces/stack-trace-analyzer/ICalleeDataExtractor.d.ts b/src/interfaces/stack-trace-analyzer/ICalleeDataExtractor.d.ts new file mode 100644 index 00000000..1903565f --- /dev/null +++ b/src/interfaces/stack-trace-analyzer/ICalleeDataExtractor.d.ts @@ -0,0 +1,5 @@ +import { ICalleeData } from './ICalleeData'; + +export interface ICalleeDataExtractor { + extract (): ICalleeData|null; +} diff --git a/src/interfaces/IAnalyzer.d.ts b/src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer.d.ts similarity index 100% rename from src/interfaces/IAnalyzer.d.ts rename to src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer.d.ts diff --git a/src/interfaces/stack-trace-analyzer/IStackTraceData.d.ts b/src/interfaces/stack-trace-analyzer/IStackTraceData.d.ts new file mode 100644 index 00000000..cdd71e63 --- /dev/null +++ b/src/interfaces/stack-trace-analyzer/IStackTraceData.d.ts @@ -0,0 +1,5 @@ +import { ICalleeData } from './ICalleeData'; + +export interface IStackTraceData extends ICalleeData { + stackTrace: IStackTraceData[]; +} diff --git a/src/stack-trace-analyzer/StackTraceAnalyzer.ts b/src/stack-trace-analyzer/StackTraceAnalyzer.ts new file mode 100644 index 00000000..ab0d4919 --- /dev/null +++ b/src/stack-trace-analyzer/StackTraceAnalyzer.ts @@ -0,0 +1,110 @@ +import * as estraverse from 'estraverse'; +import * as ESTree from 'estree'; + +import { TCalleeDataExtractor } from '../types/TCalleeDataExtractor'; + +import { ICalleeData } from '../interfaces/stack-trace-analyzer/ICalleeData'; +import { IStackTraceAnalyzer } from '../interfaces/stack-trace-analyzer/IStackTraceAnalyzer'; +import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData'; + +import { NodeType } from '../enums/NodeType'; + +import { FunctionDeclarationCalleeDataExtractor } from './callee-data-extractors/FunctionDeclarationCalleeDataExtractor'; +import { FunctionExpressionCalleeDataExtractor } from './callee-data-extractors/FunctionExpressionCalleeDataExtractor'; +import { Nodes } from '../Nodes'; +import { NodeUtils } from '../NodeUtils'; + +/** + * This class generates a data with code stack trace functions calls + * + * For example: + * + * function Foo () { + * var baz = function () { + * + * } + * + * baz(); + * } + * + * foo(); + * + * Will generate a structure like: + * + * [ + * { + * callee: FOO_FUNCTION_NODE + * name: 'Foo', + * trace: [ + * { + * callee: BAZ_FUNCTION_NODE, + * name: 'baz, + * trace: [] + * } + * ] + * } + * ] + */ +export class StackTraceAnalyzer implements IStackTraceAnalyzer { + /** + * @type {ESTree.Node[]} + */ + private blockScopeBody: ESTree.Node[]; + + /** + * @type {Map} + */ + private calleeDataExtractors: Map = new Map ([ + [NodeType.FunctionDeclaration, FunctionDeclarationCalleeDataExtractor], + [NodeType.FunctionExpression, FunctionExpressionCalleeDataExtractor] + ]); + + /** + * @param blockScopeBody + */ + constructor (blockScopeBody: ESTree.Node[]) { + this.blockScopeBody = blockScopeBody; + } + + /** + * @returns {IStackTraceData[]} + */ + public analyze (): IStackTraceData[] { + return this.analyzeRecursive(this.blockScopeBody); + } + + /** + * @param blockScopeBody + * @returns {IStackTraceData[]} + */ + private analyzeRecursive (blockScopeBody: ESTree.Node[]): IStackTraceData[] { + const stackTraceData: IStackTraceData[] = []; + + for (let rootNode of blockScopeBody) { + estraverse.traverse(rootNode, { + enter: (node: ESTree.Node): any => { + if (!Nodes.isCallExpressionNode(node) || rootNode.parentNode !== NodeUtils.getBlockScopeOfNode(node)) { + return; + } + + this.calleeDataExtractors.forEach((calleeDataExtractor: TCalleeDataExtractor) => { + const calleeData: ICalleeData|null = new calleeDataExtractor( + blockScopeBody, + node.callee + ).extract(); + + if (!calleeData) { + return; + } + + stackTraceData.push(Object.assign({}, calleeData, { + stackTrace: this.analyzeRecursive(calleeData.callee.body) + })); + }); + } + }); + } + + return stackTraceData; + } +} diff --git a/src/stack-trace-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor.ts b/src/stack-trace-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor.ts new file mode 100644 index 00000000..fcf85562 --- /dev/null +++ b/src/stack-trace-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor.ts @@ -0,0 +1,75 @@ +import * as estraverse from 'estraverse'; +import * as ESTree from 'estree'; + +import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; + +import { ICalleeData } from '../../interfaces/stack-trace-analyzer/ICalleeData'; +import { ICalleeDataExtractor } from '../../interfaces/stack-trace-analyzer/ICalleeDataExtractor'; + +import { Nodes } from '../../Nodes'; +import { NodeUtils } from '../../NodeUtils'; + +export class FunctionDeclarationCalleeDataExtractor implements ICalleeDataExtractor { + /** + * @type {ESTree.Node[]} + */ + private blockScopeBody: ESTree.Node[]; + + /** + * @type {ESTree.Identifier} + */ + private callee: ESTree.Identifier; + + /** + * @param blockScopeBody + * @param callee + */ + constructor (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier) { + this.blockScopeBody = blockScopeBody; + this.callee = callee; + } + + /** + * @returns {ICalleeData|null} + */ + public extract (): ICalleeData|null { + let calleeBlockStatement: TNodeWithBlockStatement|null = null; + + if (Nodes.isIdentifierNode(this.callee)) { + calleeBlockStatement = this.getCalleeBlockStatement( + NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), + this.callee.name + ); + } + + if (!calleeBlockStatement) { + return null; + } + + return { + callee: calleeBlockStatement, + name: this.callee.name + }; + } + + /** + * @param node + * @param name + * @returns {TNodeWithBlockStatement|null} + */ + private getCalleeBlockStatement (node: ESTree.Node, name: string): TNodeWithBlockStatement|null { + let calleeBlockStatement: TNodeWithBlockStatement|null = null; + + estraverse.traverse(node, { + enter: (node: ESTree.Node): any => { + if (Nodes.isFunctionDeclarationNode(node) && node.id.name === name) { + calleeBlockStatement = node.body; + + return estraverse.VisitorOption.Break; + } + } + }); + + return calleeBlockStatement; + } +} diff --git a/src/stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts b/src/stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts new file mode 100644 index 00000000..1cf55116 --- /dev/null +++ b/src/stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts @@ -0,0 +1,80 @@ +import * as estraverse from 'estraverse'; +import * as ESTree from 'estree'; + +import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement'; + +import { ICalleeData } from '../../interfaces/stack-trace-analyzer/ICalleeData'; +import { ICalleeDataExtractor } from '../../interfaces/stack-trace-analyzer/ICalleeDataExtractor'; + +import { Nodes } from '../../Nodes'; +import { NodeUtils } from '../../NodeUtils'; + +export class FunctionExpressionCalleeDataExtractor implements ICalleeDataExtractor { + /** + * @type {ESTree.Node[]} + */ + private blockScopeBody: ESTree.Node[]; + + /** + * @type {ESTree.Identifier} + */ + private callee: ESTree.Identifier; + + /** + * @param blockScopeBody + * @param callee + */ + constructor (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier) { + this.blockScopeBody = blockScopeBody; + this.callee = callee; + } + + /** + * @returns {ICalleeData|null} + */ + public extract (): ICalleeData|null { + let calleeBlockStatement: TNodeWithBlockStatement|null = null; + + if (Nodes.isIdentifierNode(this.callee)) { + calleeBlockStatement = this.getCalleeBlockStatement( + NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), + this.callee.name + ); + } + + if (!calleeBlockStatement) { + return null; + } + + return { + callee: calleeBlockStatement, + name: this.callee.name + }; + } + + /** + * @param node + * @param name + * @returns {TNodeWithBlockStatement|null} + */ + private getCalleeBlockStatement (node: ESTree.Node, name: string): TNodeWithBlockStatement|null { + let calleeBlockStatement: TNodeWithBlockStatement|null = null; + + estraverse.traverse(node, { + enter: (node: ESTree.Node, parentNode: ESTree.Node): any => { + if ( + Nodes.isFunctionExpressionNode(node) && + Nodes.isVariableDeclaratorNode(parentNode) && + Nodes.isIdentifierNode(parentNode.id) && + parentNode.id.name === name + ) { + calleeBlockStatement = node.body; + + return estraverse.VisitorOption.Break; + } + } + }); + + return calleeBlockStatement; + } +} diff --git a/src/types/TCalleeDataExtractor.d.ts b/src/types/TCalleeDataExtractor.d.ts new file mode 100644 index 00000000..00c8c1cd --- /dev/null +++ b/src/types/TCalleeDataExtractor.d.ts @@ -0,0 +1,5 @@ +import * as ESTree from 'estree'; + +import { ICalleeDataExtractor } from '../interfaces/stack-trace-analyzer/ICalleeDataExtractor'; + +export type TCalleeDataExtractor = (new (blockScopeBody: ESTree.Node[], callee: any) => ICalleeDataExtractor); diff --git a/src/types/TNodeObfuscator.d.ts b/src/types/TNodeObfuscator.d.ts index 08e4cb6f..7dc60547 100644 --- a/src/types/TNodeObfuscator.d.ts +++ b/src/types/TNodeObfuscator.d.ts @@ -2,4 +2,4 @@ import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; import { INodeObfuscator } from '../interfaces/INodeObfuscator'; import { IOptions } from '../interfaces/IOptions'; -export type TNodeObfuscator = (new (nodes: Map , options: IOptions) => INodeObfuscator); +export type TNodeObfuscator = (new (nodes: Map , options: IOptions) => INodeObfuscator); diff --git a/test/unit-tests/StackTraceAnalyzer-spec.ts b/test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer-spec.ts similarity index 94% rename from test/unit-tests/StackTraceAnalyzer-spec.ts rename to test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer-spec.ts index 39047e9d..1a220104 100644 --- a/test/unit-tests/StackTraceAnalyzer-spec.ts +++ b/test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer-spec.ts @@ -2,15 +2,15 @@ import * as chai from 'chai'; import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; -import { TNodeWithBlockStatement } from '../../src/types/TNodeWithBlockStatement'; +import { TNodeWithBlockStatement } from '../../../src/types/TNodeWithBlockStatement'; -import { IStackTraceData } from '../../src/interfaces/IStackTraceData'; +import { IStackTraceData } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceData'; -import { readFileAsString } from '../helpers/readFileAsString'; +import { readFileAsString } from '../../helpers/readFileAsString'; -import { Nodes } from '../../src/Nodes'; -import { NodeUtils } from '../../src/NodeUtils'; -import { StackTraceAnalyzer } from '../../src/StackTraceAnalyzer'; +import { Nodes } from '../../../src/Nodes'; +import { NodeUtils } from '../../../src/NodeUtils'; +import { StackTraceAnalyzer } from '../../../src/stack-trace-analyzer/StackTraceAnalyzer'; const assert: any = chai.assert; @@ -67,7 +67,7 @@ function getFunctionExpressionByName (astTree: ESTree.Node, name: string): ESTre } describe('StackTraceAnalyzer', () => { - describe('analyze (): IStackTraceData[]', () => { + describe('extract (): IStackTraceData[]', () => { let astTree: TNodeWithBlockStatement, stackTraceData: IStackTraceData[], expectedStackTraceData: IStackTraceData[]; diff --git a/test/index.spec.ts b/test/index.spec.ts index 3bbf6379..1e957c4b 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -14,7 +14,6 @@ import './unit-tests/SourceMapCorrector.spec'; import './unit-tests/Utils.spec'; import './unit-tests/cli/CLIUtils.spec'; import './unit-tests/custom-nodes/CustomNodeAppender-spec'; -import './unit-tests/StackTraceAnalyzer-spec'; import './unit-tests/node-obfuscators/CatchClauseObfuscator.spec'; import './unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec'; import './unit-tests/node-obfuscators/FunctionObfuscator.spec'; @@ -37,5 +36,6 @@ import './functional-tests/node-obfuscators/MemberExpressionObfuscator.spec'; import './functional-tests/node-obfuscators/MethodDefinitionObfuscator.spec'; import './functional-tests/node-obfuscators/ObjectExpressionObfuscator.spec'; import './functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec'; +import './functional-tests/stack-trace-analyzer/StackTraceAnalyzer-spec'; import './functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec'; import './functional-tests/templates/custom-nodes/unicode-array-nodes/UnicodeArrayDecodeNodeTemplate.spec';