Explorar o código

Added new types and interfaces for Nodes, tests fixes

sanex3339 %!s(int64=8) %!d(string=hai) anos
pai
achega
ab7bbd2b9e

+ 70 - 70
dist/index.js

@@ -93,7 +93,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__(41);
+var chance_1 = __webpack_require__(42);
 var JSFuck_1 = __webpack_require__(10);
 
 var Utils = function () {
@@ -849,19 +849,19 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
 var estraverse = __webpack_require__(3);
 var AppendState_1 = __webpack_require__(6);
 var NodeType_1 = __webpack_require__(2);
-var CatchClauseObfuscator_1 = __webpack_require__(33);
-var ConsoleOutputNodesGroup_1 = __webpack_require__(47);
-var DebugProtectionNodesGroup_1 = __webpack_require__(30);
-var FunctionDeclarationObfuscator_1 = __webpack_require__(34);
-var FunctionObfuscator_1 = __webpack_require__(35);
-var LiteralObfuscator_1 = __webpack_require__(36);
-var MemberExpressionObfuscator_1 = __webpack_require__(37);
-var MethodDefinitionObfuscator_1 = __webpack_require__(38);
+var CatchClauseObfuscator_1 = __webpack_require__(34);
+var ConsoleOutputNodesGroup_1 = __webpack_require__(30);
+var DebugProtectionNodesGroup_1 = __webpack_require__(31);
+var FunctionDeclarationObfuscator_1 = __webpack_require__(35);
+var FunctionObfuscator_1 = __webpack_require__(36);
+var LiteralObfuscator_1 = __webpack_require__(37);
+var MemberExpressionObfuscator_1 = __webpack_require__(38);
+var MethodDefinitionObfuscator_1 = __webpack_require__(39);
 var NodeUtils_1 = __webpack_require__(1);
-var ObjectExpressionObfuscator_1 = __webpack_require__(39);
-var SelfDefendingNodesGroup_1 = __webpack_require__(31);
-var UnicodeArrayNodesGroup_1 = __webpack_require__(32);
-var VariableDeclarationObfuscator_1 = __webpack_require__(40);
+var ObjectExpressionObfuscator_1 = __webpack_require__(40);
+var SelfDefendingNodesGroup_1 = __webpack_require__(32);
+var UnicodeArrayNodesGroup_1 = __webpack_require__(33);
+var VariableDeclarationObfuscator_1 = __webpack_require__(41);
 
 var Obfuscator = function () {
     function Obfuscator(options) {
@@ -1063,11 +1063,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_1 = __webpack_require__(43);
-var fs = __webpack_require__(44);
-var mkdirp = __webpack_require__(45);
-var path = __webpack_require__(46);
-var child_process_1 = __webpack_require__(42);
+var commander_1 = __webpack_require__(44);
+var fs = __webpack_require__(45);
+var mkdirp = __webpack_require__(46);
+var path = __webpack_require__(47);
+var child_process_1 = __webpack_require__(43);
 var DefaultPreset_1 = __webpack_require__(14);
 var JavaScriptObfuscator_1 = __webpack_require__(9);
 
@@ -1862,6 +1862,42 @@ 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 ConsoleOutputDisableExpressionNode_1 = __webpack_require__(21);
+var NodesGroup_1 = __webpack_require__(12);
+
+var ConsoleOutputNodesGroup = function (_NodesGroup_1$NodesGr) {
+    _inherits(ConsoleOutputNodesGroup, _NodesGroup_1$NodesGr);
+
+    function ConsoleOutputNodesGroup(options) {
+        _classCallCheck(this, ConsoleOutputNodesGroup);
+
+        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ConsoleOutputNodesGroup).call(this, options));
+
+        if (!_this.options.get('disableConsoleOutput')) {
+            return _possibleConstructorReturn(_this);
+        }
+        _this.nodes.set('consoleOutputDisableExpressionNode', new ConsoleOutputDisableExpressionNode_1.ConsoleOutputDisableExpressionNode(_this.options));
+        return _this;
+    }
+
+    return ConsoleOutputNodesGroup;
+}(NodesGroup_1.NodesGroup);
+
+exports.ConsoleOutputNodesGroup = ConsoleOutputNodesGroup;
+
+/***/ },
+/* 31 */
+/***/ function(module, exports, __webpack_require__) {
+
+"use strict";
+"use strict";
+
+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 DebugProtectionFunctionCallNode_1 = __webpack_require__(22);
 var DebugProtectionFunctionIntervalNode_1 = __webpack_require__(23);
 var DebugProtectionFunctionNode_1 = __webpack_require__(24);
@@ -1894,7 +1930,7 @@ var DebugProtectionNodesGroup = function (_NodesGroup_1$NodesGr) {
 exports.DebugProtectionNodesGroup = DebugProtectionNodesGroup;
 
 /***/ },
-/* 31 */
+/* 32 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1930,7 +1966,7 @@ var SelfDefendingNodesGroup = function (_NodesGroup_1$NodesGr) {
 exports.SelfDefendingNodesGroup = SelfDefendingNodesGroup;
 
 /***/ },
-/* 32 */
+/* 33 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1991,7 +2027,7 @@ var UnicodeArrayNodesGroup = function (_NodesGroup_1$NodesGr) {
 exports.UnicodeArrayNodesGroup = UnicodeArrayNodesGroup;
 
 /***/ },
-/* 33 */
+/* 34 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2062,7 +2098,7 @@ var CatchClauseObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.CatchClauseObfuscator = CatchClauseObfuscator;
 
 /***/ },
-/* 34 */
+/* 35 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2139,7 +2175,7 @@ var FunctionDeclarationObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.FunctionDeclarationObfuscator = FunctionDeclarationObfuscator;
 
 /***/ },
-/* 35 */
+/* 36 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2216,7 +2252,7 @@ var FunctionObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.FunctionObfuscator = FunctionObfuscator;
 
 /***/ },
-/* 36 */
+/* 37 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2281,7 +2317,7 @@ var LiteralObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.LiteralObfuscator = LiteralObfuscator;
 
 /***/ },
-/* 37 */
+/* 38 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2365,7 +2401,7 @@ var MemberExpressionObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.MemberExpressionObfuscator = MemberExpressionObfuscator;
 
 /***/ },
-/* 38 */
+/* 39 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2431,7 +2467,7 @@ var MethodDefinitionObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.MethodDefinitionObfuscator = MethodDefinitionObfuscator;
 
 /***/ },
-/* 39 */
+/* 40 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2514,7 +2550,7 @@ var ObjectExpressionObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.ObjectExpressionObfuscator = ObjectExpressionObfuscator;
 
 /***/ },
-/* 40 */
+/* 41 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2608,77 +2644,41 @@ var VariableDeclarationObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.VariableDeclarationObfuscator = VariableDeclarationObfuscator;
 
 /***/ },
-/* 41 */
+/* 42 */
 /***/ function(module, exports) {
 
 module.exports = require("chance");
 
 /***/ },
-/* 42 */
+/* 43 */
 /***/ function(module, exports) {
 
 module.exports = require("child_process");
 
 /***/ },
-/* 43 */
+/* 44 */
 /***/ function(module, exports) {
 
 module.exports = require("commander");
 
 /***/ },
-/* 44 */
+/* 45 */
 /***/ function(module, exports) {
 
 module.exports = require("fs");
 
 /***/ },
-/* 45 */
+/* 46 */
 /***/ function(module, exports) {
 
 module.exports = require("mkdirp");
 
 /***/ },
-/* 46 */
+/* 47 */
 /***/ function(module, exports) {
 
 module.exports = require("path");
 
-/***/ },
-/* 47 */
-/***/ function(module, exports, __webpack_require__) {
-
-"use strict";
-"use strict";
-
-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 ConsoleOutputDisableExpressionNode_1 = __webpack_require__(21);
-var NodesGroup_1 = __webpack_require__(12);
-
-var ConsoleOutputNodesGroup = function (_NodesGroup_1$NodesGr) {
-    _inherits(ConsoleOutputNodesGroup, _NodesGroup_1$NodesGr);
-
-    function ConsoleOutputNodesGroup(options) {
-        _classCallCheck(this, ConsoleOutputNodesGroup);
-
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ConsoleOutputNodesGroup).call(this, options));
-
-        if (!_this.options.get('disableConsoleOutput')) {
-            return _possibleConstructorReturn(_this);
-        }
-        _this.nodes.set('consoleOutputDisableExpressionNode', new ConsoleOutputDisableExpressionNode_1.ConsoleOutputDisableExpressionNode(_this.options));
-        return _this;
-    }
-
-    return ConsoleOutputNodesGroup;
-}(NodesGroup_1.NodesGroup);
-
-exports.ConsoleOutputNodesGroup = ConsoleOutputNodesGroup;
-
 /***/ }
 /******/ ]);
 //# sourceMappingURL=index.js.map

+ 2 - 1
src/NodeUtils.ts

@@ -3,6 +3,7 @@ import * as estraverse from 'estraverse';
 import { INode } from './interfaces/nodes/INode';
 
 import { TNodeWithBlockStatement } from "./types/TNodeWithBlockStatement";
+import { TStatement } from "./types/TStatement";
 
 import { NodeType } from "./enums/NodeType";
 
@@ -116,7 +117,7 @@ export class NodeUtils {
                 Object.defineProperty(node, 'parentNode', {
                     configurable: true,
                     enumerable: true,
-                    value: isRootNode ? Nodes.getProgramNode([node]) : parentNode || node,
+                    value: isRootNode ? Nodes.getProgramNode(<TStatement[]>[node]) : parentNode || node,
                     writable: true
                 });
 

+ 3 - 1
src/Nodes.ts

@@ -7,6 +7,8 @@ import { IProgramNode } from "./interfaces/nodes/IProgramNode";
 import { IPropertyNode } from "./interfaces/nodes/IPropertyNode";
 import { IVariableDeclaratorNode } from "./interfaces/nodes/IVariableDeclaratorNode";
 
+import { TStatement } from "./types/TStatement";
+
 import { TNodeWithBlockStatement } from "./types/TNodeWithBlockStatement";
 
 import { NodeType } from "./enums/NodeType";
@@ -16,7 +18,7 @@ export class Nodes {
      * @param bodyNode
      * @returns IProgramNode
      */
-    public static getProgramNode (bodyNode: INode[]): IProgramNode {
+    public static getProgramNode (bodyNode: TStatement[]): IProgramNode {
         return {
             'type': NodeType.Program,
             'body': bodyNode

+ 3 - 1
src/interfaces/nodes/IBlockStatementNode.d.ts

@@ -1,5 +1,7 @@
+import { TStatement } from "../../types/TStatement";
+
 import { INode } from "./INode";
 
 export interface IBlockStatementNode extends INode {
-    body: INode[];
+    body: TStatement[];
 }

+ 9 - 0
src/interfaces/nodes/ICallExpressionNode.d.ts

@@ -0,0 +1,9 @@
+import { TExpression } from "../../types/TExpression";
+
+import { INode } from "./INode";
+import { ISpreadElementNode } from "./ISpreadElementNode";
+
+export interface ICallExpressionNode extends INode {
+    callee: TExpression;
+    arguments: TExpression[] | ISpreadElementNode[];
+}

+ 3 - 1
src/interfaces/nodes/IExpressionStatementNode.d.ts

@@ -1,5 +1,7 @@
+import { TExpression } from "../../types/TExpression";
+
 import { INode } from "./INode";
 
 export interface IExpressionStatementNode extends INode {
-    expression: any;
+    expression: TExpression;
 }

+ 3 - 0
src/interfaces/nodes/IFunctionNode.d.ts

@@ -1,3 +1,5 @@
+import { TExpression } from "../../types/TExpression";
+
 import { IBlockStatementNode } from "./IBlockStatementNode";
 import { IIdentifierNode } from "./IIdentifierNode";
 import { INode } from "./INode";
@@ -5,6 +7,7 @@ import { INode } from "./INode";
 export interface IFunctionNode extends INode {
     id: IIdentifierNode;
     params: IIdentifierNode[];
+    defaults?: TExpression[];
     body: IBlockStatementNode;
     generator: boolean;
     expression: boolean;

+ 1 - 1
src/interfaces/nodes/ILiteralNode.d.ts

@@ -3,5 +3,5 @@ import { INode } from "./INode";
 export interface ILiteralNode extends INode {
     value: boolean|number|string;
     raw: string;
-    'x-verbatim-property': any;
+    'x-verbatim-property'?: any;
 }

+ 3 - 1
src/interfaces/nodes/IProgramNode.d.ts

@@ -1,5 +1,7 @@
+import { TStatement } from "../../types/TStatement";
+
 import { INode } from "./INode";
 
 export interface IProgramNode extends INode {
-    body: INode[];
+    body: TStatement[];
 }

+ 7 - 0
src/interfaces/nodes/ISpreadElementNode.d.ts

@@ -0,0 +1,7 @@
+import { TExpression } from "../../types/TExpression";
+
+import { INode } from "./INode";
+
+export interface ISpreadElementNode extends INode {
+    argument: TExpression;
+}

+ 10 - 0
src/types/TExpression.d.ts

@@ -0,0 +1,10 @@
+import { IArrowFunctionExpressionNode } from "../interfaces/nodes/IArrowFunctionExpressionNode";
+import { ICallExpressionNode } from "../interfaces/nodes/ICallExpressionNode";
+import { IFunctionExpressionNode } from "../interfaces/nodes/IFunctionExpressionNode";
+import { IIdentifierNode } from "../interfaces/nodes/IIdentifierNode";
+import { ILiteralNode } from "../interfaces/nodes/ILiteralNode";
+import { IMemberExpressionNode } from "../interfaces/nodes/IMemberExpressionNode";
+import { INode } from "../interfaces/nodes/INode";
+
+export type TExpression = INode & (IArrowFunctionExpressionNode | ICallExpressionNode | IFunctionExpressionNode |
+    IIdentifierNode | ILiteralNode | IMemberExpressionNode);

+ 8 - 0
src/types/TStatement.d.ts

@@ -0,0 +1,8 @@
+import { IExpressionStatementNode } from "../interfaces/nodes/IExpressionStatementNode";
+import { IFunctionDeclarationNode } from "../interfaces/nodes/IFunctionDeclarationNode";
+import { IIfStatementNode } from "../interfaces/nodes/IIfStatementNode";
+import { INode } from "../interfaces/nodes/INode";
+import { IVariableDeclarationNode } from "../interfaces/nodes/IVariableDeclarationNode";
+
+export type TStatement = INode & (IExpressionStatementNode | IFunctionDeclarationNode | IIfStatementNode |
+    IVariableDeclarationNode);

+ 60 - 62
test/NodeUtils.spec.ts

@@ -1,8 +1,7 @@
 import { IBlockStatementNode } from "../src/interfaces/nodes/IBlockStatementNode";
+import { IExpressionStatementNode } from "../src/interfaces/nodes/IExpressionStatementNode";
 import { IFunctionDeclarationNode } from "../src/interfaces/nodes/IFunctionDeclarationNode";
-import { IIdentifierNode } from "../src/interfaces/nodes/IIdentifierNode";
 import { IIfStatementNode } from "../src/interfaces/nodes/IIfStatementNode";
-import { ILiteralNode } from "../src/interfaces/nodes/ILiteralNode";
 import { INode } from "../src/interfaces/nodes/INode";
 import { IProgramNode } from "../src/interfaces/nodes/IProgramNode";
 
@@ -33,17 +32,17 @@ describe('NodeUtils', () => {
     describe('appendNode (blockScopeBody: INode[], node: INode): void', () => {
         let blockStatementNode: IBlockStatementNode,
             expectedBlockStatementNode: IBlockStatementNode,
-            identifierNode: IIdentifierNode;
+            expressionStatementNode: IExpressionStatementNode;
 
         beforeEach(() => {
-            identifierNode = NodeMocks.getIdentifierNode();
+            expressionStatementNode = NodeMocks.getExpressionStatementNode();
 
             blockStatementNode = NodeMocks.getBlockStatementNode();
 
             expectedBlockStatementNode = Object.assign({}, blockStatementNode);
-            expectedBlockStatementNode.body.push(identifierNode);
+            expectedBlockStatementNode.body.push(expressionStatementNode);
 
-            NodeUtils.appendNode(blockStatementNode.body, identifierNode);
+            NodeUtils.appendNode(blockStatementNode.body, expressionStatementNode);
         });
 
         it('should append given node to a `BlockStatement` node body', () => {
@@ -67,23 +66,22 @@ describe('NodeUtils', () => {
 
     describe('getBlockStatementNodeByIndex (node: INode, index: number = 0): INode', () => {
         let blockStatementNode: IBlockStatementNode,
-            identifierNode: IIdentifierNode,
-            literalNode: ILiteralNode;
+            expressionStatementNode1: IExpressionStatementNode,
+            expressionStatementNode2: IExpressionStatementNode;
 
         beforeEach(() => {
-            identifierNode = NodeMocks.getIdentifierNode();
-
-            literalNode = NodeMocks.getLiteralNode();
+            expressionStatementNode1 = NodeMocks.getExpressionStatementNode();
+            expressionStatementNode2 = NodeMocks.getExpressionStatementNode();
 
             blockStatementNode = NodeMocks.getBlockStatementNode([
-                identifierNode,
-                literalNode
+                expressionStatementNode1,
+                expressionStatementNode2
             ]);
         });
 
         it('should return block-statement child node of given node if that node has block-statement', () => {
-            assert.deepEqual(NodeUtils.getBlockStatementNodeByIndex(blockStatementNode), identifierNode);
-            assert.deepEqual(NodeUtils.getBlockStatementNodeByIndex(blockStatementNode, 1), literalNode);
+            assert.deepEqual(NodeUtils.getBlockStatementNodeByIndex(blockStatementNode), expressionStatementNode1);
+            assert.deepEqual(NodeUtils.getBlockStatementNodeByIndex(blockStatementNode, 1), expressionStatementNode2);
         });
 
         it('should throw a `ReferenceError` if index is out of boundaries', () => {
@@ -91,7 +89,7 @@ describe('NodeUtils', () => {
         });
 
         it('should throw a `TypeError` if node have no a block-statement', () => {
-            assert.throws(() => NodeUtils.getBlockStatementNodeByIndex(identifierNode, 1), TypeError);
+            assert.throws(() => NodeUtils.getBlockStatementNodeByIndex(expressionStatementNode1, 1), TypeError);
         });
     });
 
@@ -101,21 +99,20 @@ describe('NodeUtils', () => {
             ifStatementBlockStatementNode2: IBlockStatementNode,
             ifStatementNode1: IIfStatementNode,
             ifStatementNode2: IIfStatementNode,
-            identifierNode: IIdentifierNode,
+            expressionStatementNode1: IExpressionStatementNode,
+            expressionStatementNode2: IExpressionStatementNode,
+            expressionStatementNode3: IExpressionStatementNode,
             functionDeclarationNode: IFunctionDeclarationNode,
-            literalNode1: ILiteralNode,
-            literalNode2: ILiteralNode,
             programNode: IProgramNode;
 
         beforeEach(() => {
-            identifierNode = NodeMocks.getIdentifierNode();
-
-            literalNode1 = NodeMocks.getLiteralNode();
-            literalNode2 = NodeMocks.getLiteralNode();
+            expressionStatementNode1 = NodeMocks.getExpressionStatementNode();
+            expressionStatementNode2 = NodeMocks.getExpressionStatementNode();
+            expressionStatementNode3 = NodeMocks.getExpressionStatementNode();
 
             ifStatementBlockStatementNode2 = NodeMocks.getBlockStatementNode([
-                literalNode1,
-                literalNode2
+                expressionStatementNode1,
+                expressionStatementNode2
             ]);
 
             ifStatementNode2 = NodeMocks.getIfStatementNode(ifStatementBlockStatementNode2);
@@ -127,7 +124,7 @@ describe('NodeUtils', () => {
             ifStatementNode1 = NodeMocks.getIfStatementNode(ifStatementBlockStatementNode1);
 
             functionDeclarationBlockStatementNode = NodeMocks.getBlockStatementNode([
-                identifierNode,
+                expressionStatementNode3,
                 ifStatementNode1
             ]);
 
@@ -140,47 +137,46 @@ describe('NodeUtils', () => {
             programNode['parentNode'] = programNode;
             functionDeclarationNode['parentNode'] = programNode;
             functionDeclarationBlockStatementNode['parentNode'] = functionDeclarationNode;
-            identifierNode['parentNode'] = functionDeclarationBlockStatementNode;
+            expressionStatementNode3['parentNode'] = functionDeclarationBlockStatementNode;
             ifStatementNode1['parentNode'] = functionDeclarationBlockStatementNode;
             ifStatementBlockStatementNode1['parentNode'] = ifStatementNode1;
             ifStatementNode2['parentNode'] = ifStatementBlockStatementNode1;
             ifStatementBlockStatementNode2['parentNode'] = ifStatementNode2;
-            literalNode1['parentNode'] = ifStatementBlockStatementNode2;
+            expressionStatementNode1['parentNode'] = ifStatementBlockStatementNode2;
         });
 
         it('should return block-scope node for given node', () => {
-            assert.deepEqual(NodeUtils.getBlockScopeOfNode(identifierNode), functionDeclarationBlockStatementNode);
-            assert.deepEqual(NodeUtils.getBlockScopeOfNode(identifierNode, 1), programNode);
+            assert.deepEqual(NodeUtils.getBlockScopeOfNode(expressionStatementNode3), functionDeclarationBlockStatementNode);
+            assert.deepEqual(NodeUtils.getBlockScopeOfNode(expressionStatementNode3, 1), programNode);
             assert.deepEqual(NodeUtils.getBlockScopeOfNode(functionDeclarationNode), programNode);
             assert.deepEqual(NodeUtils.getBlockScopeOfNode(functionDeclarationBlockStatementNode), programNode);
             assert.deepEqual(NodeUtils.getBlockScopeOfNode(programNode), programNode);
-            assert.deepEqual(NodeUtils.getBlockScopeOfNode(literalNode1), functionDeclarationBlockStatementNode);
+            assert.deepEqual(NodeUtils.getBlockScopeOfNode(expressionStatementNode1), functionDeclarationBlockStatementNode);
         });
 
         it('should throw a `ReferenceError` if node has no `parentNode` property', () => {
-            assert.throws(() => NodeUtils.getBlockScopeOfNode(literalNode2), ReferenceError);
+            assert.throws(() => NodeUtils.getBlockScopeOfNode(expressionStatementNode2), ReferenceError);
         });
     });
 
     describe('insertNodeAtIndex (blockScopeBody: INode[], node: INode, index: number): void', () => {
         let blockStatementNode: IBlockStatementNode,
             expectedBlockStatementNode: IBlockStatementNode,
-            identifierNode: IIdentifierNode,
-            literalNode: ILiteralNode;
+            expressionStatementNode1: IExpressionStatementNode,
+            expressionStatementNode2: IExpressionStatementNode;
 
         beforeEach(() => {
-            identifierNode = NodeMocks.getIdentifierNode();
-
-            literalNode = NodeMocks.getLiteralNode();
+            expressionStatementNode1 = NodeMocks.getExpressionStatementNode();
+            expressionStatementNode2 = NodeMocks.getExpressionStatementNode();
 
             blockStatementNode = NodeMocks.getBlockStatementNode([
-                identifierNode
+                expressionStatementNode1
             ]);
 
             expectedBlockStatementNode = Object.assign({}, blockStatementNode);
-            expectedBlockStatementNode['body'].push(literalNode);
+            expectedBlockStatementNode['body'].push(expressionStatementNode2);
 
-            NodeUtils.insertNodeAtIndex(blockStatementNode.body, literalNode, 1);
+            NodeUtils.insertNodeAtIndex(blockStatementNode.body, expressionStatementNode2, 1);
         });
 
         it('should insert given node in `BlockStatement` node body at index', () => {
@@ -203,54 +199,56 @@ describe('NodeUtils', () => {
     });
 
     describe('parentize (node: INode): void', () => {
-        let blockStatementNode: IBlockStatementNode,
-            identifierNode: IIdentifierNode,
-            literalNode: ILiteralNode,
+        let ifStatementNode: IIfStatementNode,
+            ifStatementBlockStatementNode: IBlockStatementNode,
+            expressionStatementNode1: IExpressionStatementNode,
+            expressionStatementNode2: IExpressionStatementNode,
             programNode: IProgramNode;
 
         beforeEach(() => {
-            identifierNode = NodeMocks.getIdentifierNode();
+            expressionStatementNode1 = NodeMocks.getExpressionStatementNode();
+            expressionStatementNode2 = NodeMocks.getExpressionStatementNode();
 
-            literalNode = NodeMocks.getLiteralNode();
-
-            blockStatementNode = NodeMocks.getBlockStatementNode([
-                identifierNode,
-                literalNode
+            ifStatementBlockStatementNode = NodeMocks.getBlockStatementNode([
+                expressionStatementNode1,
+                expressionStatementNode2
             ]);
 
+            ifStatementNode = NodeMocks.getIfStatementNode(ifStatementBlockStatementNode);
+
             programNode = NodeMocks.getProgramNode([
-                blockStatementNode
+                ifStatementNode
             ]);
 
-            NodeUtils.parentize(blockStatementNode);
+            NodeUtils.parentize(ifStatementNode);
         });
 
         it('should parentize given AST-tree', () => {
-            assert.deepEqual(blockStatementNode['parentNode'], programNode);
-            assert.deepEqual(identifierNode['parentNode'], blockStatementNode);
-            assert.deepEqual(literalNode['parentNode'], blockStatementNode);
+            assert.deepEqual(ifStatementNode['parentNode'], programNode);
+            assert.deepEqual(ifStatementBlockStatementNode['parentNode'], ifStatementNode);
+            assert.deepEqual(expressionStatementNode1['parentNode'], ifStatementBlockStatementNode);
+            assert.deepEqual(expressionStatementNode2['parentNode'], ifStatementBlockStatementNode);
         });
     });
 
     describe('prependNode (blockScopeBody: INode[], node: INode): void', () => {
         let blockStatementNode: IBlockStatementNode,
             expectedBlockStatementNode: IBlockStatementNode,
-            identifierNode: IIdentifierNode,
-            literalNode: ILiteralNode;
+            expressionStatementNode1: IExpressionStatementNode,
+            expressionStatementNode2: IExpressionStatementNode;
 
         beforeEach(() => {
-            identifierNode = NodeMocks.getIdentifierNode();
-
-            literalNode = NodeMocks.getLiteralNode();
+            expressionStatementNode1 = NodeMocks.getExpressionStatementNode();
+            expressionStatementNode2 = NodeMocks.getExpressionStatementNode();
 
             blockStatementNode = NodeMocks.getBlockStatementNode([
-                identifierNode
+                expressionStatementNode1
             ]);
 
             expectedBlockStatementNode = Object.assign({}, blockStatementNode);
-            expectedBlockStatementNode['body'].unshift(literalNode);
+            expectedBlockStatementNode['body'].unshift(expressionStatementNode2);
 
-            NodeUtils.prependNode(blockStatementNode.body, literalNode);
+            NodeUtils.prependNode(blockStatementNode.body, expressionStatementNode2);
         });
 
         it('should prepend given node to a `BlockStatement` node body', () => {

+ 17 - 5
test/mocks/NodeMocks.ts

@@ -1,10 +1,12 @@
+import { TStatement } from "../../src/types/TStatement";
+
 import { IBlockStatementNode } from "../../src/interfaces/nodes/IBlockStatementNode";
 import { ICatchClauseNode } from "../../src/interfaces/nodes/ICatchClauseNode";
+import { IExpressionStatementNode } from "../../src/interfaces/nodes/IExpressionStatementNode";
 import { IFunctionDeclarationNode } from "../../src/interfaces/nodes/IFunctionDeclarationNode";
 import { IIdentifierNode } from "../../src/interfaces/nodes/IIdentifierNode";
 import { IIfStatementNode } from "../../src/interfaces/nodes/IIfStatementNode";
 import { ILiteralNode } from "../../src/interfaces/nodes/ILiteralNode";
-import { INode } from "../../src/interfaces/nodes/INode";
 import { IProgramNode } from "../../src/interfaces/nodes/IProgramNode";
 
 import { NodeType } from "../../src/enums/NodeType";
@@ -14,7 +16,7 @@ export class NodeMocks {
      * @param bodyNodes
      * @returns {IProgramNode}
      */
-    public static getProgramNode (bodyNodes: INode[] = []): IProgramNode {
+    public static getProgramNode (bodyNodes: TStatement[] = []): IProgramNode {
         return {
             type: NodeType.Program,
             body: bodyNodes
@@ -25,7 +27,7 @@ export class NodeMocks {
      * @param bodyNodes
      * @returns {IBlockStatementNode}
      */
-    public static getBlockStatementNode (bodyNodes: INode[] = []): IBlockStatementNode {
+    public static getBlockStatementNode (bodyNodes: TStatement[] = []): IBlockStatementNode {
         return {
             type: NodeType.BlockStatement,
             body: bodyNodes
@@ -36,7 +38,7 @@ export class NodeMocks {
      * @param bodyNodes
      * @returns {ICatchClauseNode}
      */
-    public static getCatchClauseNode (bodyNodes: INode[] = []): ICatchClauseNode {
+    public static getCatchClauseNode (bodyNodes: TStatement[] = []): ICatchClauseNode {
         return {
             type: NodeType.CatchClause,
             param: NodeMocks.getIdentifierNode('err'),
@@ -44,6 +46,16 @@ export class NodeMocks {
         };
     }
 
+    /**
+     * @returns {IExpressionStatementNode}
+     */
+    public static getExpressionStatementNode (): IExpressionStatementNode {
+        return {
+            type: NodeType.ExpressionStatement,
+            expression: NodeMocks.getIdentifierNode()
+        };
+    }
+
     /**
      * @param functionName
      * @param blockStatementNode
@@ -99,4 +111,4 @@ export class NodeMocks {
             'x-verbatim-property': `'string'`
         };
     }
-}
+}

+ 27 - 25
test/node-obfuscators/CatchClauseObfuscator.spec.ts

@@ -1,6 +1,6 @@
 import { ICatchClauseNode } from "../../src/interfaces/nodes/ICatchClauseNode";
 import { ICustomNode } from "../../src/interfaces/ICustomNode";
-import { INode } from "../../src/interfaces/nodes/INode";
+import { IExpressionStatementNode } from "../../src/interfaces/nodes/IExpressionStatementNode";
 
 import { DEFAULT_PRESET } from "../../src/preset-options/DefaultPreset";
 
@@ -18,36 +18,38 @@ describe('CatchClauseObfuscator', () => {
             catchClauseNode: ICatchClauseNode;
 
         beforeEach(() => {
+            let expressionStatementNode: IExpressionStatementNode = {
+                type: NodeType.ExpressionStatement,
+                expression: {
+                    type: NodeType.CallExpression,
+                    callee: {
+                        type: NodeType.MemberExpression,
+                        computed: false,
+                        object: {
+                            type: NodeType.Identifier,
+                            name: 'console'
+                        },
+                        property: {
+                            type: NodeType.Identifier,
+                            name: 'log'
+                        }
+                    },
+                    arguments: [
+                        {
+                            type: NodeType.Identifier,
+                            'name': 'err'
+                        }
+                    ]
+                }
+            };
+
             catchClauseObfuscator = new CatchClauseObfuscator(
                 new Map<string, ICustomNode>(),
                 new Options(DEFAULT_PRESET)
             );
 
             catchClauseNode = NodeMocks.getCatchClauseNode([
-                <INode>{
-                    type: NodeType.ExpressionStatement,
-                    expression: {
-                        type: NodeType.CallExpression,
-                        callee: {
-                            type: NodeType.MemberExpression,
-                            computed: false,
-                            object: {
-                                type: NodeType.Identifier,
-                                name: 'console'
-                            },
-                            property: {
-                                type: NodeType.Identifier,
-                                name: 'log'
-                            }
-                        },
-                        arguments: [
-                            {
-                                type: NodeType.Identifier,
-                                'name': 'err'
-                            }
-                        ]
-                    }
-                }
+                expressionStatementNode
             ]);
 
             catchClauseObfuscator.obfuscateNode(catchClauseNode);

+ 3 - 3
test/node-obfuscators/FunctionDeclarationObfuscator.spec.ts

@@ -1,7 +1,7 @@
 import { IBlockStatementNode } from "../../src/interfaces/nodes/IBlockStatementNode";
 import { ICustomNode } from "../../src/interfaces/ICustomNode";
+import { IExpressionStatementNode } from "../../src/interfaces/nodes/IExpressionStatementNode";
 import { IFunctionDeclarationNode } from "../../src/interfaces/nodes/IFunctionDeclarationNode";
-import { INode } from "../../src/interfaces/nodes/INode";
 import { IProgramNode } from "../../src/interfaces/nodes/IProgramNode";
 
 import { NodeType } from "../../src/enums/NodeType";
@@ -16,14 +16,14 @@ const assert: Chai.AssertStatic = require('chai').assert;
 
 describe('FunctionDeclarationObfuscator', () => {
     describe('obfuscateNode (functionDeclarationNode: IFunctionDeclarationNode, parentNode: INode): void', () => {
-        let expressionStatementNode: INode,
+        let expressionStatementNode: IExpressionStatementNode,
             functionDeclarationObfuscator: FunctionDeclarationObfuscator,
             functionDeclarationNode: IFunctionDeclarationNode,
             functionName: string = 'functionDeclaration',
             programNode: IProgramNode;
 
         beforeEach(() => {
-            expressionStatementNode = <INode>{
+            expressionStatementNode = {
                 type: NodeType.ExpressionStatement,
                 expression: {
                     type: NodeType.CallExpression,