diff --git a/dist/index.js b/dist/index.js index 4cfc63e9..d640bce9 100644 --- a/dist/index.js +++ b/dist/index.js @@ -360,9 +360,11 @@ module.exports = require("inversify"); "use strict"; exports.ServiceIdentifiers = { + 'Factory': Symbol('Factory'), 'Factory': Symbol('Factory'), 'Factory': Symbol('Factory'), 'Factory': Symbol('Factory'), + ICalleeDataExtractor: Symbol('ICalleeDataExtractor'), IControlFlowReplacer: Symbol('IControlFlowReplacer'), IJavaScriptObfuscator: Symbol('IJavaScriptObfuscator'), INodeTransformer: Symbol('INodeTransformer'), @@ -2083,12 +2085,12 @@ var ServiceIdentifiers_1 = __webpack_require__(2); var NodeControlFlowTransformersModule_1 = __webpack_require__(37); var NodeObfuscatorsModule_1 = __webpack_require__(38); var NodeTransformersModule_1 = __webpack_require__(39); +var StackTraceAnalyzerModule_1 = __webpack_require__(114); var CustomNodesStorage_1 = __webpack_require__(83); var JavaScriptObfuscatorInternal_1 = __webpack_require__(31); var ObfuscationEventEmitter_1 = __webpack_require__(59); var Obfuscator_1 = __webpack_require__(32); var Options_1 = __webpack_require__(74); -var StackTraceAnalyzer_1 = __webpack_require__(77); var InversifyContainerFacade = function () { function InversifyContainerFacade(options) { @@ -2101,8 +2103,8 @@ var InversifyContainerFacade = function () { }).inSingletonScope(); this.container.bind(ServiceIdentifiers_1.ServiceIdentifiers.IObfuscator).to(Obfuscator_1.Obfuscator).inSingletonScope(); this.container.bind(ServiceIdentifiers_1.ServiceIdentifiers.IObfuscationEventEmitter).to(ObfuscationEventEmitter_1.ObfuscationEventEmitter).inSingletonScope(); - this.container.bind(ServiceIdentifiers_1.ServiceIdentifiers.IStackTraceAnalyzer).to(StackTraceAnalyzer_1.StackTraceAnalyzer).inSingletonScope(); this.container.bind(ServiceIdentifiers_1.ServiceIdentifiers['IStorage']).to(CustomNodesStorage_1.CustomNodesStorage).inSingletonScope(); + this.container.load(StackTraceAnalyzerModule_1.stackTraceAnalyzerModule); this.container.load(NodeTransformersModule_1.nodeTransformersModule); this.container.load(NodeControlFlowTransformersModule_1.nodeControlFlowTransformersModule); this.container.load(NodeObfuscatorsModule_1.nodeObfuscatorsModule); @@ -4951,19 +4953,22 @@ 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 __param = undefined && undefined.__param || function (paramIndex, decorator) { + return function (target, key) { + decorator(target, key, paramIndex); + }; +}; var inversify_1 = __webpack_require__(1); +var ServiceIdentifiers_1 = __webpack_require__(2); var estraverse = __webpack_require__(6); -var NodeType_1 = __webpack_require__(9); -var FunctionDeclarationCalleeDataExtractor_1 = __webpack_require__(78); -var FunctionExpressionCalleeDataExtractor_1 = __webpack_require__(79); -var ObjectExpressionCalleeDataExtractor_1 = __webpack_require__(80); +var CalleeDataExtractors_1 = __webpack_require__(115); var Node_1 = __webpack_require__(4); var NodeUtils_1 = __webpack_require__(10); var StackTraceAnalyzer_1 = function () { - function StackTraceAnalyzer() { + function StackTraceAnalyzer(calleeDataExtractorsFactory) { _classCallCheck(this, StackTraceAnalyzer); - this.calleeDataExtractors = new Map([[NodeType_1.NodeType.FunctionDeclaration, FunctionDeclarationCalleeDataExtractor_1.FunctionDeclarationCalleeDataExtractor], [NodeType_1.NodeType.FunctionExpression, FunctionExpressionCalleeDataExtractor_1.FunctionExpressionCalleeDataExtractor], [NodeType_1.NodeType.ObjectExpression, ObjectExpressionCalleeDataExtractor_1.ObjectExpressionCalleeDataExtractor]]); + this.calleeDataExtractorsFactory = calleeDataExtractorsFactory; } _createClass(StackTraceAnalyzer, [{ @@ -4989,8 +4994,8 @@ var StackTraceAnalyzer_1 = function () { if (!Node_1.Node.isCallExpressionNode(node) || rootNode.parentNode !== NodeUtils_1.NodeUtils.getBlockScopeOfNode(node)) { return; } - _this.calleeDataExtractors.forEach(function (calleeDataExtractor) { - var calleeData = new calleeDataExtractor(blockScopeBody, node.callee).extract(); + StackTraceAnalyzer_1.calleeDataExtractorsList.forEach(function (calleeDataExtractorName) { + var calleeData = _this.calleeDataExtractorsFactory(calleeDataExtractorName).extract(blockScopeBody, node.callee); if (!calleeData) { return; } @@ -5028,9 +5033,10 @@ var StackTraceAnalyzer_1 = function () { return StackTraceAnalyzer; }(); var StackTraceAnalyzer = StackTraceAnalyzer_1; +StackTraceAnalyzer.calleeDataExtractorsList = [CalleeDataExtractors_1.CalleeDataExtractors.FunctionDeclarationCalleeDataExtractor, CalleeDataExtractors_1.CalleeDataExtractors.FunctionExpressionCalleeDataExtractor, CalleeDataExtractors_1.CalleeDataExtractors.ObjectExpressionCalleeDataExtractor]; StackTraceAnalyzer.limitThresholdActivationLength = 25; StackTraceAnalyzer.limitThreshold = 0.002; -StackTraceAnalyzer = StackTraceAnalyzer_1 = __decorate([inversify_1.injectable(), __metadata('design:paramtypes', [])], StackTraceAnalyzer); +StackTraceAnalyzer = StackTraceAnalyzer_1 = __decorate([inversify_1.injectable(), __param(0, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers['Factory'])), __metadata('design:paramtypes', [Function])], StackTraceAnalyzer); exports.StackTraceAnalyzer = StackTraceAnalyzer; /***/ }, @@ -5042,37 +5048,56 @@ exports.StackTraceAnalyzer = StackTraceAnalyzer; 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 _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +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 __decorate = undefined && undefined.__decorate || function (decorators, target, key, desc) { + var c = arguments.length, + r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, + d; + if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) { + if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + }return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +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 inversify_1 = __webpack_require__(1); var estraverse = __webpack_require__(6); +var AbstractCalleeDataExtractor_1 = __webpack_require__(116); var Node_1 = __webpack_require__(4); var NodeUtils_1 = __webpack_require__(10); +var FunctionDeclarationCalleeDataExtractor = function (_AbstractCalleeDataEx) { + _inherits(FunctionDeclarationCalleeDataExtractor, _AbstractCalleeDataEx); -var FunctionDeclarationCalleeDataExtractor = function () { - function FunctionDeclarationCalleeDataExtractor(blockScopeBody, callee) { + function FunctionDeclarationCalleeDataExtractor() { _classCallCheck(this, FunctionDeclarationCalleeDataExtractor); - this.blockScopeBody = blockScopeBody; - this.callee = callee; + return _possibleConstructorReturn(this, (FunctionDeclarationCalleeDataExtractor.__proto__ || Object.getPrototypeOf(FunctionDeclarationCalleeDataExtractor)).apply(this, arguments)); } _createClass(FunctionDeclarationCalleeDataExtractor, [{ - key: 'extract', - value: function extract() { + key: "extract", + value: function extract(blockScopeBody, callee) { var calleeBlockStatement = null; - if (Node_1.Node.isIdentifierNode(this.callee)) { - calleeBlockStatement = this.getCalleeBlockStatement(NodeUtils_1.NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), this.callee.name); + if (Node_1.Node.isIdentifierNode(callee)) { + calleeBlockStatement = this.getCalleeBlockStatement(NodeUtils_1.NodeUtils.getBlockScopeOfNode(blockScopeBody[0]), callee.name); } if (!calleeBlockStatement) { return null; } return { callee: calleeBlockStatement, - name: this.callee.name + name: callee.name }; } }, { - key: 'getCalleeBlockStatement', + key: "getCalleeBlockStatement", value: function getCalleeBlockStatement(node, name) { var calleeBlockStatement = null; estraverse.traverse(node, { @@ -5088,8 +5113,8 @@ var FunctionDeclarationCalleeDataExtractor = function () { }]); return FunctionDeclarationCalleeDataExtractor; -}(); - +}(AbstractCalleeDataExtractor_1.AbstractCalleeDataExtractor); +FunctionDeclarationCalleeDataExtractor = __decorate([inversify_1.injectable(), __metadata('design:paramtypes', [])], FunctionDeclarationCalleeDataExtractor); exports.FunctionDeclarationCalleeDataExtractor = FunctionDeclarationCalleeDataExtractor; /***/ }, @@ -5101,40 +5126,59 @@ exports.FunctionDeclarationCalleeDataExtractor = FunctionDeclarationCalleeDataEx 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 _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +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 __decorate = undefined && undefined.__decorate || function (decorators, target, key, desc) { + var c = arguments.length, + r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, + d; + if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) { + if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + }return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +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 inversify_1 = __webpack_require__(1); var estraverse = __webpack_require__(6); +var AbstractCalleeDataExtractor_1 = __webpack_require__(116); var Node_1 = __webpack_require__(4); var NodeUtils_1 = __webpack_require__(10); +var FunctionExpressionCalleeDataExtractor = function (_AbstractCalleeDataEx) { + _inherits(FunctionExpressionCalleeDataExtractor, _AbstractCalleeDataEx); -var FunctionExpressionCalleeDataExtractor = function () { - function FunctionExpressionCalleeDataExtractor(blockScopeBody, callee) { + function FunctionExpressionCalleeDataExtractor() { _classCallCheck(this, FunctionExpressionCalleeDataExtractor); - this.blockScopeBody = blockScopeBody; - this.callee = callee; + return _possibleConstructorReturn(this, (FunctionExpressionCalleeDataExtractor.__proto__ || Object.getPrototypeOf(FunctionExpressionCalleeDataExtractor)).apply(this, arguments)); } _createClass(FunctionExpressionCalleeDataExtractor, [{ - key: 'extract', - value: function extract() { + key: "extract", + value: function extract(blockScopeBody, callee) { var calleeBlockStatement = null; - if (Node_1.Node.isIdentifierNode(this.callee)) { - calleeBlockStatement = this.getCalleeBlockStatement(NodeUtils_1.NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), this.callee.name); + if (Node_1.Node.isIdentifierNode(callee)) { + calleeBlockStatement = this.getCalleeBlockStatement(NodeUtils_1.NodeUtils.getBlockScopeOfNode(blockScopeBody[0]), callee.name); } - if (Node_1.Node.isFunctionExpressionNode(this.callee)) { - calleeBlockStatement = this.callee.body; + if (Node_1.Node.isFunctionExpressionNode(callee)) { + calleeBlockStatement = callee.body; } if (!calleeBlockStatement) { return null; } return { callee: calleeBlockStatement, - name: this.callee.name || null + name: callee.name || null }; } }, { - key: 'getCalleeBlockStatement', + key: "getCalleeBlockStatement", value: function getCalleeBlockStatement(node, name) { var calleeBlockStatement = null; estraverse.traverse(node, { @@ -5150,8 +5194,8 @@ var FunctionExpressionCalleeDataExtractor = function () { }]); return FunctionExpressionCalleeDataExtractor; -}(); - +}(AbstractCalleeDataExtractor_1.AbstractCalleeDataExtractor); +FunctionExpressionCalleeDataExtractor = __decorate([inversify_1.injectable(), __metadata('design:paramtypes', [])], FunctionExpressionCalleeDataExtractor); exports.FunctionExpressionCalleeDataExtractor = FunctionExpressionCalleeDataExtractor; /***/ }, @@ -5163,32 +5207,51 @@ exports.FunctionExpressionCalleeDataExtractor = FunctionExpressionCalleeDataExtr 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 _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +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 __decorate = undefined && undefined.__decorate || function (decorators, target, key, desc) { + var c = arguments.length, + r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, + d; + if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) { + if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + }return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +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 inversify_1 = __webpack_require__(1); var estraverse = __webpack_require__(6); var Node_1 = __webpack_require__(4); var NodeUtils_1 = __webpack_require__(10); +var AbstractCalleeDataExtractor_1 = __webpack_require__(116); +var ObjectExpressionCalleeDataExtractor = function (_AbstractCalleeDataEx) { + _inherits(ObjectExpressionCalleeDataExtractor, _AbstractCalleeDataEx); -var ObjectExpressionCalleeDataExtractor = function () { - function ObjectExpressionCalleeDataExtractor(blockScopeBody, callee) { + function ObjectExpressionCalleeDataExtractor() { _classCallCheck(this, ObjectExpressionCalleeDataExtractor); - this.blockScopeBody = blockScopeBody; - this.callee = callee; + return _possibleConstructorReturn(this, (ObjectExpressionCalleeDataExtractor.__proto__ || Object.getPrototypeOf(ObjectExpressionCalleeDataExtractor)).apply(this, arguments)); } _createClass(ObjectExpressionCalleeDataExtractor, [{ - key: 'extract', - value: function extract() { + key: "extract", + value: function extract(blockScopeBody, callee) { var calleeBlockStatement = null, functionExpressionName = null; - if (Node_1.Node.isMemberExpressionNode(this.callee)) { - var objectMembersCallsChain = this.createObjectMembersCallsChain([], this.callee); + if (Node_1.Node.isMemberExpressionNode(callee)) { + var objectMembersCallsChain = this.createObjectMembersCallsChain([], callee); if (!objectMembersCallsChain.length) { return null; } functionExpressionName = objectMembersCallsChain[objectMembersCallsChain.length - 1]; - calleeBlockStatement = this.getCalleeBlockStatement(NodeUtils_1.NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), objectMembersCallsChain); + calleeBlockStatement = this.getCalleeBlockStatement(NodeUtils_1.NodeUtils.getBlockScopeOfNode(blockScopeBody[0]), objectMembersCallsChain); } if (!calleeBlockStatement) { return null; @@ -5199,7 +5262,7 @@ var ObjectExpressionCalleeDataExtractor = function () { }; } }, { - key: 'createObjectMembersCallsChain', + key: "createObjectMembersCallsChain", value: function createObjectMembersCallsChain(currentChain, memberExpression) { if (Node_1.Node.isIdentifierNode(memberExpression.property) && memberExpression.computed === false) { currentChain.unshift(memberExpression.property.name); @@ -5216,9 +5279,9 @@ var ObjectExpressionCalleeDataExtractor = function () { return currentChain; } }, { - key: 'getCalleeBlockStatement', + key: "getCalleeBlockStatement", value: function getCalleeBlockStatement(node, objectMembersCallsChain) { - var _this = this; + var _this2 = this; var objectName = objectMembersCallsChain.shift(); if (!objectName) { @@ -5228,7 +5291,7 @@ var ObjectExpressionCalleeDataExtractor = function () { estraverse.traverse(node, { enter: function enter(node, parentNode) { if (Node_1.Node.isVariableDeclaratorNode(node) && Node_1.Node.isIdentifierNode(node.id) && node.init && Node_1.Node.isObjectExpressionNode(node.init) && node.id.name === objectName) { - calleeBlockStatement = _this.findCalleeBlockStatement(node.init.properties, objectMembersCallsChain); + calleeBlockStatement = _this2.findCalleeBlockStatement(node.init.properties, objectMembersCallsChain); return estraverse.VisitorOption.Break; } } @@ -5236,7 +5299,7 @@ var ObjectExpressionCalleeDataExtractor = function () { return calleeBlockStatement; } }, { - key: 'findCalleeBlockStatement', + key: "findCalleeBlockStatement", value: function findCalleeBlockStatement(objectExpressionProperties, objectMembersCallsChain) { var nextItemInCallsChain = objectMembersCallsChain.shift(); if (!nextItemInCallsChain) { @@ -5282,8 +5345,8 @@ var ObjectExpressionCalleeDataExtractor = function () { }]); return ObjectExpressionCalleeDataExtractor; -}(); - +}(AbstractCalleeDataExtractor_1.AbstractCalleeDataExtractor); +ObjectExpressionCalleeDataExtractor = __decorate([inversify_1.injectable(), __metadata('design:paramtypes', [])], ObjectExpressionCalleeDataExtractor); exports.ObjectExpressionCalleeDataExtractor = ObjectExpressionCalleeDataExtractor; /***/ }, @@ -5805,6 +5868,82 @@ module.exports = require("reflect-metadata"); var JavaScriptObfuscator_1 = __webpack_require__(13); module.exports = JavaScriptObfuscator_1.JavaScriptObfuscator; +/***/ }, +/* 114 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var inversify_1 = __webpack_require__(1); +var ServiceIdentifiers_1 = __webpack_require__(2); +var FunctionDeclarationCalleeDataExtractor_1 = __webpack_require__(78); +var FunctionExpressionCalleeDataExtractor_1 = __webpack_require__(79); +var ObjectExpressionCalleeDataExtractor_1 = __webpack_require__(80); +var StackTraceAnalyzer_1 = __webpack_require__(77); +var CalleeDataExtractors_1 = __webpack_require__(115); +exports.stackTraceAnalyzerModule = new inversify_1.ContainerModule(function (bind) { + var calleeDataExtractorsTag = 'calleeDataExtractors'; + bind(ServiceIdentifiers_1.ServiceIdentifiers.IStackTraceAnalyzer).to(StackTraceAnalyzer_1.StackTraceAnalyzer).inSingletonScope(); + bind(ServiceIdentifiers_1.ServiceIdentifiers.ICalleeDataExtractor).to(FunctionDeclarationCalleeDataExtractor_1.FunctionDeclarationCalleeDataExtractor).whenTargetTagged(calleeDataExtractorsTag, CalleeDataExtractors_1.CalleeDataExtractors.FunctionDeclarationCalleeDataExtractor); + bind(ServiceIdentifiers_1.ServiceIdentifiers.ICalleeDataExtractor).to(FunctionExpressionCalleeDataExtractor_1.FunctionExpressionCalleeDataExtractor).whenTargetTagged(calleeDataExtractorsTag, CalleeDataExtractors_1.CalleeDataExtractors.FunctionExpressionCalleeDataExtractor); + bind(ServiceIdentifiers_1.ServiceIdentifiers.ICalleeDataExtractor).to(ObjectExpressionCalleeDataExtractor_1.ObjectExpressionCalleeDataExtractor).whenTargetTagged(calleeDataExtractorsTag, CalleeDataExtractors_1.CalleeDataExtractors.ObjectExpressionCalleeDataExtractor); + bind(ServiceIdentifiers_1.ServiceIdentifiers['Factory']).toFactory(function (context) { + var cache = new Map(); + return function (calleeDataExtractorName) { + if (cache.has(calleeDataExtractorName)) { + return cache.get(calleeDataExtractorName); + } + var calleeDataExtractor = context.container.getTagged(ServiceIdentifiers_1.ServiceIdentifiers.ICalleeDataExtractor, calleeDataExtractorsTag, calleeDataExtractorName); + cache.set(calleeDataExtractorName, calleeDataExtractor); + return calleeDataExtractor; + }; + }); +}); + +/***/ }, +/* 115 */ +/***/ function(module, exports) { + +"use strict"; +"use strict"; + +(function (CalleeDataExtractors) { + CalleeDataExtractors[CalleeDataExtractors["FunctionDeclarationCalleeDataExtractor"] = 0] = "FunctionDeclarationCalleeDataExtractor"; + CalleeDataExtractors[CalleeDataExtractors["FunctionExpressionCalleeDataExtractor"] = 1] = "FunctionExpressionCalleeDataExtractor"; + CalleeDataExtractors[CalleeDataExtractors["ObjectExpressionCalleeDataExtractor"] = 2] = "ObjectExpressionCalleeDataExtractor"; +})(exports.CalleeDataExtractors || (exports.CalleeDataExtractors = {})); +var CalleeDataExtractors = exports.CalleeDataExtractors; + +/***/ }, +/* 116 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; +"use strict"; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var __decorate = undefined && undefined.__decorate || function (decorators, target, key, desc) { + var c = arguments.length, + r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, + d; + if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) { + if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + }return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +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 inversify_1 = __webpack_require__(1); +var AbstractCalleeDataExtractor = function AbstractCalleeDataExtractor() { + _classCallCheck(this, AbstractCalleeDataExtractor); +}; +AbstractCalleeDataExtractor = __decorate([inversify_1.injectable(), __metadata('design:paramtypes', [])], AbstractCalleeDataExtractor); +exports.AbstractCalleeDataExtractor = AbstractCalleeDataExtractor; + /***/ } /******/ ]); //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/src/JavaScriptObfuscatorInternal.ts b/src/JavaScriptObfuscatorInternal.ts index 30e47904..c500c26f 100644 --- a/src/JavaScriptObfuscatorInternal.ts +++ b/src/JavaScriptObfuscatorInternal.ts @@ -37,12 +37,12 @@ export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator { }; /** - * @types {IStorage} + * @type {IStorage} */ private readonly customNodesStorage: IStorage; /** - * @types {IObfuscator} + * @type {IObfuscator} */ private readonly obfuscator: IObfuscator; diff --git a/src/container/InversifyContainerFacade.ts b/src/container/InversifyContainerFacade.ts index 2f8901c9..e5a8519b 100644 --- a/src/container/InversifyContainerFacade.ts +++ b/src/container/InversifyContainerFacade.ts @@ -4,14 +4,15 @@ import { ServiceIdentifiers } from './ServiceIdentifiers'; import { nodeControlFlowTransformersModule } from './modules/node-transformers/NodeControlFlowTransformersModule'; import { nodeObfuscatorsModule } from './modules/node-transformers/NodeObfuscatorsModule'; import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule'; +import { stackTraceAnalyzerModule } from './modules/stack-trace-analyzer/StackTraceAnalyzerModule'; import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode'; import { IInputOptions } from '../interfaces/IInputOptions'; +import { IInversifyContainerFacade } from '../interfaces/container/IInversifyContainerFacade'; import { IJavaScriptObfuscator } from '../interfaces/IJavaScriptObfsucator'; import { IObfuscationEventEmitter } from '../interfaces/IObfuscationEventEmitter'; import { IObfuscator } from '../interfaces/IObfuscator'; import { IOptions } from '../interfaces/IOptions'; -import { IStackTraceAnalyzer } from '../interfaces/stack-trace-analyzer/IStackTraceAnalyzer'; import { IStorage } from '../interfaces/IStorage'; import { CustomNodesStorage } from '../storages/custom-nodes/CustomNodesStorage'; @@ -19,9 +20,8 @@ import { JavaScriptObfuscatorInternal } from '../JavaScriptObfuscatorInternal'; import { ObfuscationEventEmitter } from '../event-emitters/ObfuscationEventEmitter'; import { Obfuscator } from '../Obfuscator'; import { Options } from "../options/Options"; -import { StackTraceAnalyzer } from '../stack-trace-analyzer/StackTraceAnalyzer'; -export class InversifyContainerFacade { +export class InversifyContainerFacade implements IInversifyContainerFacade { /** * @type {interfaces.Container} */ @@ -55,17 +55,13 @@ export class InversifyContainerFacade { .to(ObfuscationEventEmitter) .inSingletonScope(); - this.container - .bind(ServiceIdentifiers.IStackTraceAnalyzer) - .to(StackTraceAnalyzer) - .inSingletonScope(); - this.container .bind>(ServiceIdentifiers['IStorage']) .to(CustomNodesStorage) .inSingletonScope(); // modules + this.container.load(stackTraceAnalyzerModule); this.container.load(nodeTransformersModule); this.container.load(nodeControlFlowTransformersModule); this.container.load(nodeObfuscatorsModule); diff --git a/src/container/ServiceIdentifiers.ts b/src/container/ServiceIdentifiers.ts index 8857247c..47788e72 100644 --- a/src/container/ServiceIdentifiers.ts +++ b/src/container/ServiceIdentifiers.ts @@ -1,9 +1,11 @@ import { IContainerServiceIdentifiers } from '../interfaces/container/IContainerServiceIdentifiers'; export const ServiceIdentifiers: IContainerServiceIdentifiers = { + 'Factory': Symbol('Factory'), 'Factory': Symbol('Factory'), 'Factory': Symbol('Factory'), 'Factory': Symbol('Factory'), + ICalleeDataExtractor: Symbol('ICalleeDataExtractor'), IControlFlowReplacer: Symbol('IControlFlowReplacer'), IJavaScriptObfuscator: Symbol('IJavaScriptObfuscator'), INodeTransformer: Symbol('INodeTransformer'), diff --git a/src/container/modules/stack-trace-analyzer/StackTraceAnalyzerModule.ts b/src/container/modules/stack-trace-analyzer/StackTraceAnalyzerModule.ts new file mode 100644 index 00000000..ecb871fb --- /dev/null +++ b/src/container/modules/stack-trace-analyzer/StackTraceAnalyzerModule.ts @@ -0,0 +1,55 @@ +import { ContainerModule, interfaces } from 'inversify'; +import { ServiceIdentifiers } from '../../ServiceIdentifiers'; + +import { ICalleeDataExtractor } from '../../../interfaces/stack-trace-analyzer/ICalleeDataExtractor'; +import { IStackTraceAnalyzer } from '../../../interfaces/stack-trace-analyzer/IStackTraceAnalyzer'; + +import { FunctionDeclarationCalleeDataExtractor } from '../../../stack-trace-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor'; +import { FunctionExpressionCalleeDataExtractor } from '../../../stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor'; +import { ObjectExpressionCalleeDataExtractor } from '../../../stack-trace-analyzer/callee-data-extractors/ObjectExpressionCalleeDataExtractor'; +import { StackTraceAnalyzer } from '../../../stack-trace-analyzer/StackTraceAnalyzer'; +import { CalleeDataExtractors } from '../../../enums/container/CalleeDataExtractors'; + +export const stackTraceAnalyzerModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => { + const calleeDataExtractorsTag: string = 'calleeDataExtractors'; + + // stack trace analyzer + bind(ServiceIdentifiers.IStackTraceAnalyzer) + .to(StackTraceAnalyzer) + .inSingletonScope(); + + // callee data extractors + bind(ServiceIdentifiers.ICalleeDataExtractor) + .to(FunctionDeclarationCalleeDataExtractor) + .whenTargetTagged(calleeDataExtractorsTag, CalleeDataExtractors.FunctionDeclarationCalleeDataExtractor); + + bind(ServiceIdentifiers.ICalleeDataExtractor) + .to(FunctionExpressionCalleeDataExtractor) + .whenTargetTagged(calleeDataExtractorsTag, CalleeDataExtractors.FunctionExpressionCalleeDataExtractor); + + bind(ServiceIdentifiers.ICalleeDataExtractor) + .to(ObjectExpressionCalleeDataExtractor) + .whenTargetTagged(calleeDataExtractorsTag, CalleeDataExtractors.ObjectExpressionCalleeDataExtractor); + + // node transformers factory + bind(ServiceIdentifiers['Factory']) + .toFactory((context: interfaces.Context) => { + const cache: Map = new Map (); + + return (calleeDataExtractorName: CalleeDataExtractors) => { + if (cache.has(calleeDataExtractorName)) { + return cache.get(calleeDataExtractorName); + } + + const calleeDataExtractor: ICalleeDataExtractor = context.container.getTagged( + ServiceIdentifiers.ICalleeDataExtractor, + calleeDataExtractorsTag, + calleeDataExtractorName + ); + + cache.set(calleeDataExtractorName, calleeDataExtractor); + + return calleeDataExtractor; + }; + }); +}); diff --git a/src/enums/container/CalleeDataExtractors.ts b/src/enums/container/CalleeDataExtractors.ts new file mode 100644 index 00000000..d6f0a63c --- /dev/null +++ b/src/enums/container/CalleeDataExtractors.ts @@ -0,0 +1,5 @@ +export enum CalleeDataExtractors { + FunctionDeclarationCalleeDataExtractor, + FunctionExpressionCalleeDataExtractor, + ObjectExpressionCalleeDataExtractor, +} diff --git a/src/interfaces/container/IContainerServiceIdentifiers.d.ts b/src/interfaces/container/IContainerServiceIdentifiers.d.ts index d91252b5..e138b4f5 100644 --- a/src/interfaces/container/IContainerServiceIdentifiers.d.ts +++ b/src/interfaces/container/IContainerServiceIdentifiers.d.ts @@ -1,9 +1,11 @@ import { interfaces } from 'inversify'; export interface IContainerServiceIdentifiers { + 'Factory': interfaces.ServiceIdentifier; 'Factory': interfaces.ServiceIdentifier; 'Factory': interfaces.ServiceIdentifier; 'Factory': interfaces.ServiceIdentifier; + ICalleeDataExtractor: interfaces.ServiceIdentifier; IControlFlowReplacer: interfaces.ServiceIdentifier; IJavaScriptObfuscator: interfaces.ServiceIdentifier; INodeTransformer: interfaces.ServiceIdentifier; diff --git a/src/interfaces/stack-trace-analyzer/ICalleeDataExtractor.d.ts b/src/interfaces/stack-trace-analyzer/ICalleeDataExtractor.d.ts index 1903565f..3e80f548 100644 --- a/src/interfaces/stack-trace-analyzer/ICalleeDataExtractor.d.ts +++ b/src/interfaces/stack-trace-analyzer/ICalleeDataExtractor.d.ts @@ -1,5 +1,7 @@ +import * as ESTree from 'estree'; + import { ICalleeData } from './ICalleeData'; export interface ICalleeDataExtractor { - extract (): ICalleeData|null; + extract (blockScopeBody: ESTree.Node[], callee: ESTree.Node): ICalleeData|null; } diff --git a/src/stack-trace-analyzer/StackTraceAnalyzer.ts b/src/stack-trace-analyzer/StackTraceAnalyzer.ts index bb6ddf72..5fa9585b 100644 --- a/src/stack-trace-analyzer/StackTraceAnalyzer.ts +++ b/src/stack-trace-analyzer/StackTraceAnalyzer.ts @@ -1,19 +1,17 @@ -import { injectable } from 'inversify'; +import { injectable, inject } from 'inversify'; +import { ServiceIdentifiers } from '../container/ServiceIdentifiers'; import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; -import { TCalleeDataExtractor } from '../types/TCalleeDataExtractor'; +import { TCalleeDataExtractorsFactory } from '../types/TCalleeDataExtractorsFactory'; import { ICalleeData } from '../interfaces/stack-trace-analyzer/ICalleeData'; +import { ICalleeDataExtractor } from '../interfaces/stack-trace-analyzer/ICalleeDataExtractor'; 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 { ObjectExpressionCalleeDataExtractor } from './callee-data-extractors/ObjectExpressionCalleeDataExtractor'; +import { CalleeDataExtractors } from '../enums/container/CalleeDataExtractors'; import { Node } from '../node/Node'; import { NodeUtils } from '../node/NodeUtils'; @@ -51,6 +49,15 @@ import { NodeUtils } from '../node/NodeUtils'; */ @injectable() export class StackTraceAnalyzer implements IStackTraceAnalyzer { + /** + * @type {CalleeDataExtractors[]} + */ + private static readonly calleeDataExtractorsList: CalleeDataExtractors[] = [ + CalleeDataExtractors.FunctionDeclarationCalleeDataExtractor, + CalleeDataExtractors.FunctionExpressionCalleeDataExtractor, + CalleeDataExtractors.ObjectExpressionCalleeDataExtractor + ]; + /** * @type {number} */ @@ -62,13 +69,15 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer { private static readonly limitThreshold: number = 0.002; /** - * @type {Map} + * @type {(calleeDataExtractorName: CalleeDataExtractors) => ICalleeDataExtractor} */ - private readonly calleeDataExtractors: Map = new Map ([ - [NodeType.FunctionDeclaration, FunctionDeclarationCalleeDataExtractor], - [NodeType.FunctionExpression, FunctionExpressionCalleeDataExtractor], - [NodeType.ObjectExpression, ObjectExpressionCalleeDataExtractor] - ]); + private calleeDataExtractorsFactory: (calleeDataExtractorName: CalleeDataExtractors) => ICalleeDataExtractor; + + constructor ( + @inject(ServiceIdentifiers['Factory']) calleeDataExtractorsFactory: TCalleeDataExtractorsFactory + ) { + this.calleeDataExtractorsFactory = calleeDataExtractorsFactory; + } /** * @param blockScopeBodyLength @@ -126,19 +135,19 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer { return; } - this.calleeDataExtractors.forEach((calleeDataExtractor: TCalleeDataExtractor) => { - const calleeData: ICalleeData|null = new calleeDataExtractor( - blockScopeBody, - node.callee - ).extract(); + StackTraceAnalyzer.calleeDataExtractorsList.forEach((calleeDataExtractorName: CalleeDataExtractors) => { + const calleeData: ICalleeData | null = this.calleeDataExtractorsFactory(calleeDataExtractorName) + .extract(blockScopeBody, node.callee); if (!calleeData) { return; } - stackTraceData.push(Object.assign({}, calleeData, { - stackTrace: this.analyzeRecursive(calleeData.callee.body) - })); + stackTraceData.push( + Object.assign({}, calleeData, { + stackTrace: this.analyzeRecursive(calleeData.callee.body) + }) + ); }); } }); diff --git a/src/stack-trace-analyzer/callee-data-extractors/AbstractCalleeDataExtractor.ts b/src/stack-trace-analyzer/callee-data-extractors/AbstractCalleeDataExtractor.ts new file mode 100644 index 00000000..3b0d0a28 --- /dev/null +++ b/src/stack-trace-analyzer/callee-data-extractors/AbstractCalleeDataExtractor.ts @@ -0,0 +1,16 @@ +import { injectable } from 'inversify'; + +import * as ESTree from 'estree'; + +import { ICalleeData } from '../../interfaces/stack-trace-analyzer/ICalleeData'; +import { ICalleeDataExtractor } from '../../interfaces/stack-trace-analyzer/ICalleeDataExtractor'; + +@injectable() +export abstract class AbstractCalleeDataExtractor implements ICalleeDataExtractor { + /** + * @param blockScopeBody + * @param callee + * @returns {ICalleeData|null} + */ + public abstract extract (blockScopeBody: ESTree.Node[], callee: ESTree.Node): ICalleeData|null; +} diff --git a/src/stack-trace-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor.ts b/src/stack-trace-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor.ts index edce57f3..be536396 100644 --- a/src/stack-trace-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor.ts +++ b/src/stack-trace-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor.ts @@ -1,42 +1,28 @@ +import { injectable } from 'inversify'; + import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; import { ICalleeData } from '../../interfaces/stack-trace-analyzer/ICalleeData'; -import { ICalleeDataExtractor } from '../../interfaces/stack-trace-analyzer/ICalleeDataExtractor'; +import { AbstractCalleeDataExtractor } from './AbstractCalleeDataExtractor'; import { Node } from '../../node/Node'; import { NodeUtils } from '../../node/NodeUtils'; -export class FunctionDeclarationCalleeDataExtractor implements ICalleeDataExtractor { - /** - * @type {ESTree.Node[]} - */ - private blockScopeBody: ESTree.Node[]; - - /** - * @type {ESTree.Identifier} - */ - private callee: ESTree.Identifier; - +@injectable() +export class FunctionDeclarationCalleeDataExtractor extends AbstractCalleeDataExtractor { /** * @param blockScopeBody * @param callee - */ - constructor (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier) { - this.blockScopeBody = blockScopeBody; - this.callee = callee; - } - - /** * @returns {ICalleeData|null} */ - public extract (): ICalleeData|null { + public extract (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier): ICalleeData|null { let calleeBlockStatement: ESTree.BlockStatement|null = null; - if (Node.isIdentifierNode(this.callee)) { + if (Node.isIdentifierNode(callee)) { calleeBlockStatement = this.getCalleeBlockStatement( - NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), - this.callee.name + NodeUtils.getBlockScopeOfNode(blockScopeBody[0]), + callee.name ); } @@ -46,7 +32,7 @@ export class FunctionDeclarationCalleeDataExtractor implements ICalleeDataExtrac return { callee: calleeBlockStatement, - name: this.callee.name + name: callee.name }; } diff --git a/src/stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts b/src/stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts index ee7b07a3..d7d2f510 100644 --- a/src/stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts +++ b/src/stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts @@ -1,47 +1,33 @@ +import { injectable } from 'inversify'; + import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; import { ICalleeData } from '../../interfaces/stack-trace-analyzer/ICalleeData'; -import { ICalleeDataExtractor } from '../../interfaces/stack-trace-analyzer/ICalleeDataExtractor'; +import { AbstractCalleeDataExtractor } from './AbstractCalleeDataExtractor'; import { Node } from '../../node/Node'; import { NodeUtils } from '../../node/NodeUtils'; -export class FunctionExpressionCalleeDataExtractor implements ICalleeDataExtractor { - /** - * @type {ESTree.Node[]} - */ - private blockScopeBody: ESTree.Node[]; - - /** - * @type {ESTree.Identifier} - */ - private callee: ESTree.Identifier; - +@injectable() +export class FunctionExpressionCalleeDataExtractor extends AbstractCalleeDataExtractor { /** * @param blockScopeBody * @param callee - */ - constructor (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier) { - this.blockScopeBody = blockScopeBody; - this.callee = callee; - } - - /** * @returns {ICalleeData|null} */ - public extract (): ICalleeData|null { + public extract (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier): ICalleeData|null { let calleeBlockStatement: ESTree.BlockStatement|null = null; - if (Node.isIdentifierNode(this.callee)) { + if (Node.isIdentifierNode(callee)) { calleeBlockStatement = this.getCalleeBlockStatement( - NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), - this.callee.name + NodeUtils.getBlockScopeOfNode(blockScopeBody[0]), + callee.name ); } - if (Node.isFunctionExpressionNode(this.callee)) { - calleeBlockStatement = this.callee.body; + if (Node.isFunctionExpressionNode(callee)) { + calleeBlockStatement = callee.body; } if (!calleeBlockStatement) { @@ -50,7 +36,7 @@ export class FunctionExpressionCalleeDataExtractor implements ICalleeDataExtract return { callee: calleeBlockStatement, - name: this.callee.name || null + name: callee.name || null }; } diff --git a/src/stack-trace-analyzer/callee-data-extractors/ObjectExpressionCalleeDataExtractor.ts b/src/stack-trace-analyzer/callee-data-extractors/ObjectExpressionCalleeDataExtractor.ts index 43528b9b..c4ba48b6 100644 --- a/src/stack-trace-analyzer/callee-data-extractors/ObjectExpressionCalleeDataExtractor.ts +++ b/src/stack-trace-analyzer/callee-data-extractors/ObjectExpressionCalleeDataExtractor.ts @@ -1,45 +1,31 @@ +import { injectable } from 'inversify'; + import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; import { TObjectMembersCallsChain } from '../../types/TObjectMembersCallsChain'; import { ICalleeData } from '../../interfaces/stack-trace-analyzer/ICalleeData'; -import { ICalleeDataExtractor } from '../../interfaces/stack-trace-analyzer/ICalleeDataExtractor'; import { Node } from '../../node/Node'; import { NodeUtils } from '../../node/NodeUtils'; +import { AbstractCalleeDataExtractor } from './AbstractCalleeDataExtractor'; -export class ObjectExpressionCalleeDataExtractor implements ICalleeDataExtractor { - /** - * @type {ESTree.Node[]} - */ - private blockScopeBody: ESTree.Node[]; - - /** - * @type {ESTree.MemberExpression} - */ - private callee: ESTree.MemberExpression; - +@injectable() +export class ObjectExpressionCalleeDataExtractor extends AbstractCalleeDataExtractor { /** * @param blockScopeBody * @param callee - */ - constructor (blockScopeBody: ESTree.Node[], callee: ESTree.MemberExpression) { - this.blockScopeBody = blockScopeBody; - this.callee = callee; - } - - /** * @returns {ICalleeData|null} */ - public extract (): ICalleeData|null { + public extract (blockScopeBody: ESTree.Node[], callee: ESTree.MemberExpression): ICalleeData|null { let calleeBlockStatement: ESTree.BlockStatement|null = null, functionExpressionName: string|number|null = null; - if (Node.isMemberExpressionNode(this.callee)) { + if (Node.isMemberExpressionNode(callee)) { const objectMembersCallsChain: TObjectMembersCallsChain = this.createObjectMembersCallsChain( [], - this.callee + callee ); if (!objectMembersCallsChain.length) { @@ -48,7 +34,7 @@ export class ObjectExpressionCalleeDataExtractor implements ICalleeDataExtractor functionExpressionName = objectMembersCallsChain[objectMembersCallsChain.length - 1]; calleeBlockStatement = this.getCalleeBlockStatement( - NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), + NodeUtils.getBlockScopeOfNode(blockScopeBody[0]), objectMembersCallsChain ); } diff --git a/src/types/TCalleeDataExtractor.d.ts b/src/types/TCalleeDataExtractor.d.ts deleted file mode 100644 index 00c8c1cd..00000000 --- a/src/types/TCalleeDataExtractor.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -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/TCalleeDataExtractorsFactory.d.ts b/src/types/TCalleeDataExtractorsFactory.d.ts new file mode 100644 index 00000000..b242ba0c --- /dev/null +++ b/src/types/TCalleeDataExtractorsFactory.d.ts @@ -0,0 +1,5 @@ +import { ICalleeDataExtractor } from '../interfaces/stack-trace-analyzer/ICalleeDataExtractor'; + +import { CalleeDataExtractors } from '../enums/container/CalleeDataExtractors'; + +export type TCalleeDataExtractorsFactory = (calleeDataExtractorName: CalleeDataExtractors) => ICalleeDataExtractor; diff --git a/test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer.spec.ts b/test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer.spec.ts index 86859603..ca705c30 100644 --- a/test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer.spec.ts +++ b/test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer.spec.ts @@ -1,18 +1,21 @@ +import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers'; + import * as chai from 'chai'; import * as estraverse from 'estraverse'; import * as ESTree from 'estree'; import { TNodeWithBlockStatement } from '../../../src/types/TNodeWithBlockStatement'; +import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade'; import { IStackTraceAnalyzer } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer'; import { IStackTraceData } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceData'; import { readFileAsString } from '../../helpers/readFileAsString'; +import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade'; import { Node } from '../../../src/node/Node'; import { NodeMocks } from '../../mocks/NodeMocks'; import { NodeUtils } from '../../../src/node/NodeUtils'; -import { StackTraceAnalyzer } from '../../../src/stack-trace-analyzer/StackTraceAnalyzer'; const assert: any = chai.assert; @@ -146,7 +149,9 @@ function getObjectFunctionExpressionByName (astTree: ESTree.Node, objectName: st describe('StackTraceAnalyzer', () => { describe('extract (): IStackTraceData[]', () => { - const stackTraceAnalyzer: IStackTraceAnalyzer = new StackTraceAnalyzer(); + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade({}); + const stackTraceAnalyzer: IStackTraceAnalyzer = inversifyContainerFacade + .get(ServiceIdentifiers.IStackTraceAnalyzer); let astTree: TNodeWithBlockStatement, stackTraceData: IStackTraceData[], @@ -199,7 +204,7 @@ describe('StackTraceAnalyzer', () => { assert.deepEqual(stackTraceData, expectedStackTraceData); }); - it('should returns correct BlockScopeTraceData - variant #2: basic-2', () => { + it('should returns correct IStackTraceData - variant #2: basic-2', () => { astTree = NodeMocks.getProgramNode( NodeUtils.convertCodeToStructure( readFileAsString('./test/fixtures/stack-trace-analyzer/basic-2.js') @@ -235,7 +240,7 @@ describe('StackTraceAnalyzer', () => { assert.deepEqual(stackTraceData, expectedStackTraceData); }); - it('should returns correct BlockScopeTraceData - variant #3: deep conditions nesting', () => { + it('should returns correct IStackTraceData - variant #3: deep conditions nesting', () => { astTree = NodeMocks.getProgramNode( NodeUtils.convertCodeToStructure( readFileAsString('./test/fixtures/stack-trace-analyzer/deep-conditions-nesting.js') @@ -271,7 +276,7 @@ describe('StackTraceAnalyzer', () => { assert.deepEqual(stackTraceData, expectedStackTraceData); }); - it('should returns correct BlockScopeTraceData - variant #4: call before declaration', () => { + it('should returns correct IStackTraceData - variant #4: call before declaration', () => { astTree = NodeMocks.getProgramNode( NodeUtils.convertCodeToStructure( readFileAsString('./test/fixtures/stack-trace-analyzer/call-before-declaration.js') @@ -291,7 +296,7 @@ describe('StackTraceAnalyzer', () => { assert.deepEqual(stackTraceData, expectedStackTraceData); }); - it('should returns correct BlockScopeTraceData - variant #5: call expression of object member #1', () => { + it('should returns correct IStackTraceData - variant #5: call expression of object member #1', () => { astTree = NodeMocks.getProgramNode( NodeUtils.convertCodeToStructure( readFileAsString('./test/fixtures/stack-trace-analyzer/call-expression-of-object-member-1.js') @@ -347,7 +352,7 @@ describe('StackTraceAnalyzer', () => { assert.deepEqual(stackTraceData, expectedStackTraceData); }); - it('should returns correct BlockScopeTraceData - variant #5: call expression of object member #2', () => { + it('should returns correct IStackTraceData - variant #5: call expression of object member #2', () => { astTree = NodeMocks.getProgramNode( NodeUtils.convertCodeToStructure( readFileAsString('./test/fixtures/stack-trace-analyzer/call-expression-of-object-member-2.js') @@ -372,7 +377,7 @@ describe('StackTraceAnalyzer', () => { assert.deepEqual(stackTraceData, expectedStackTraceData); }); - it('should returns correct BlockScopeTraceData - variant #6: no call expressions', () => { + it('should returns correct IStackTraceData - variant #6: no call expressions', () => { astTree = NodeMocks.getProgramNode( NodeUtils.convertCodeToStructure( readFileAsString('./test/fixtures/stack-trace-analyzer/no-call-expressions.js') @@ -386,7 +391,7 @@ describe('StackTraceAnalyzer', () => { assert.deepEqual(stackTraceData, expectedStackTraceData); }); - it('should returns correct BlockScopeTraceData - variant #7: only call expression', () => { + it('should returns correct IStackTraceData - variant #7: only call expression', () => { astTree = NodeMocks.getProgramNode( NodeUtils.convertCodeToStructure( readFileAsString('./test/fixtures/stack-trace-analyzer/only-call-expression.js') @@ -400,7 +405,7 @@ describe('StackTraceAnalyzer', () => { assert.deepEqual(stackTraceData, expectedStackTraceData); }); - it('should returns correct BlockScopeTraceData - variant #8: self-invoking functions', () => { + it('should returns correct IStackTraceData - variant #8: self-invoking functions', () => { astTree = NodeMocks.getProgramNode( NodeUtils.convertCodeToStructure( readFileAsString('./test/fixtures/stack-trace-analyzer/self-invoking-functions.js') @@ -432,7 +437,7 @@ describe('StackTraceAnalyzer', () => { assert.deepEqual(stackTraceData, expectedStackTraceData); }); - it('should returns correct BlockScopeTraceData - variant #9: no recursion', () => { + it('should returns correct IStackTraceData - variant #9: no recursion', () => { astTree = NodeMocks.getProgramNode( NodeUtils.convertCodeToStructure( readFileAsString('./test/fixtures/stack-trace-analyzer/no-recursion.js') diff --git a/test/unit-tests/node/NodeAppender.spec.ts b/test/unit-tests/node/NodeAppender.spec.ts index 7db6461b..f609a710 100644 --- a/test/unit-tests/node/NodeAppender.spec.ts +++ b/test/unit-tests/node/NodeAppender.spec.ts @@ -1,17 +1,20 @@ +import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers'; + import * as chai from 'chai'; import * as ESTree from 'estree'; import { TStatement } from '../../../src/types/TStatement'; +import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade'; import { IStackTraceAnalyzer } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer'; import { IStackTraceData } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceData'; import { readFileAsString } from '../../helpers/readFileAsString'; +import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade'; import { NodeAppender } from '../../../src/node/NodeAppender'; import { NodeMocks } from '../../mocks/NodeMocks'; import { NodeUtils } from '../../../src/node/NodeUtils'; -import { StackTraceAnalyzer } from '../../../src/stack-trace-analyzer/StackTraceAnalyzer'; const assert: any = chai.assert; @@ -50,7 +53,9 @@ describe('NodeAppender', () => { }); describe('appendNodeToOptimalBlockScope (blockScopeStackTraceData: IStackTraceData[], blockScopeNode: TNodeWithBlockStatement, nodeBodyStatements: TStatement[], index: number = 0): void', () => { - const stackTraceAnalyzer: IStackTraceAnalyzer = new StackTraceAnalyzer(); + const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade({}); + const stackTraceAnalyzer: IStackTraceAnalyzer = inversifyContainerFacade + .get(ServiceIdentifiers.IStackTraceAnalyzer); let astTree: ESTree.Program, expectedAstTree: ESTree.Program,