diff --git a/dist/index.js b/dist/index.js index c166005a..079ed845 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4302,8 +4302,6 @@ var FunctionControlFlowTransformer_1; "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; }; })(); - 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"); } } @@ -4326,26 +4324,11 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var RandomGeneratorUtils_1 = __webpack_require__(2); -var AbstractControlFlowReplacer = function () { - function AbstractControlFlowReplacer(options) { - _classCallCheck(this, AbstractControlFlowReplacer); +var AbstractControlFlowReplacer = function AbstractControlFlowReplacer(options) { + _classCallCheck(this, AbstractControlFlowReplacer); - this.options = options; - } - - _createClass(AbstractControlFlowReplacer, null, [{ - key: "getStorageKey", - value: function getStorageKey() { - return RandomGeneratorUtils_1.RandomGeneratorUtils.getRandomGenerator().string({ - length: 3, - pool: RandomGeneratorUtils_1.RandomGeneratorUtils.randomGeneratorPool - }); - } - }]); - - return AbstractControlFlowReplacer; -}(); + this.options = options; +}; AbstractControlFlowReplacer = __decorate([inversify_1.injectable(), __param(0, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers.IOptions)), __metadata("design:paramtypes", [Object])], AbstractControlFlowReplacer); exports.AbstractControlFlowReplacer = AbstractControlFlowReplacer; @@ -4384,10 +4367,10 @@ var __param = undefined && undefined.__param || function (paramIndex, decorator) }; var inversify_1 = __webpack_require__(0); var ServiceIdentifiers_1 = __webpack_require__(1); -var escodegen = __webpack_require__(17); var CustomNodes_1 = __webpack_require__(13); var AbstractControlFlowReplacer_1 = __webpack_require__(69); var Node_1 = __webpack_require__(4); +var NodeUtils_1 = __webpack_require__(9); var RandomGeneratorUtils_1 = __webpack_require__(2); var BinaryExpressionControlFlowReplacer = BinaryExpressionControlFlowReplacer_1 = function (_AbstractControlFlowR) { _inherits(BinaryExpressionControlFlowReplacer, _AbstractControlFlowR); @@ -4397,7 +4380,7 @@ var BinaryExpressionControlFlowReplacer = BinaryExpressionControlFlowReplacer_1 var _this = _possibleConstructorReturn(this, (BinaryExpressionControlFlowReplacer.__proto__ || Object.getPrototypeOf(BinaryExpressionControlFlowReplacer)).call(this, options)); - _this.existingBinaryExpressionKeys = new Map(); + _this.binaryOperatorsDataByControlFlowStorageId = new Map(); _this.customNodeFactory = customNodeFactory; return _this; } @@ -4405,35 +4388,38 @@ var BinaryExpressionControlFlowReplacer = BinaryExpressionControlFlowReplacer_1 _createClass(BinaryExpressionControlFlowReplacer, [{ key: "replace", value: function replace(binaryExpressionNode, parentNode, controlFlowStorage) { - var controlFlowStorageCustomNodeName = controlFlowStorage.getStorageId(); - var binaryExpressionFunctionNode = this.customNodeFactory(CustomNodes_1.CustomNodes.BinaryExpressionFunctionNode); - var binaryExpressionOperatorKeys = this.existingBinaryExpressionKeys.get(controlFlowStorageCustomNodeName) || {}; - var controlFlowStorageCallNode = this.customNodeFactory(CustomNodes_1.CustomNodes.ControlFlowStorageCallNode); - var key = AbstractControlFlowReplacer_1.AbstractControlFlowReplacer.getStorageKey(); - if (!binaryExpressionOperatorKeys[binaryExpressionNode.operator]) { - binaryExpressionOperatorKeys[binaryExpressionNode.operator] = []; - } - binaryExpressionFunctionNode.initialize(binaryExpressionNode.operator); - if (RandomGeneratorUtils_1.RandomGeneratorUtils.getRandomFloat(0, 1) > BinaryExpressionControlFlowReplacer_1.useExistingOperatorKeyThreshold && binaryExpressionOperatorKeys[binaryExpressionNode.operator].length) { - key = RandomGeneratorUtils_1.RandomGeneratorUtils.getRandomGenerator().pickone(binaryExpressionOperatorKeys[binaryExpressionNode.operator]); + var controlFlowStorageId = controlFlowStorage.getStorageId(); + var controlFlowStorageCallCustomNode = this.customNodeFactory(CustomNodes_1.CustomNodes.ControlFlowStorageCallNode); + var storageKeysByBinaryOperator = BinaryExpressionControlFlowReplacer_1.getStorageKeysByBinaryOperatorForCurrentStorage(this.binaryOperatorsDataByControlFlowStorageId, controlFlowStorageId); + var storageKeysForCurrentOperator = storageKeysByBinaryOperator.get(binaryExpressionNode.operator); + var storageKey = void 0; + if (RandomGeneratorUtils_1.RandomGeneratorUtils.getRandomFloat(0, 1) > BinaryExpressionControlFlowReplacer_1.useExistingOperatorKeyThreshold && storageKeysForCurrentOperator && storageKeysForCurrentOperator.length) { + storageKey = RandomGeneratorUtils_1.RandomGeneratorUtils.getRandomGenerator().pickone(storageKeysForCurrentOperator); } else { - binaryExpressionOperatorKeys[binaryExpressionNode.operator].push(key); - this.existingBinaryExpressionKeys.set(controlFlowStorageCustomNodeName, binaryExpressionOperatorKeys); - controlFlowStorage.set(key, binaryExpressionFunctionNode); + var binaryExpressionFunctionCustomNode = this.customNodeFactory(CustomNodes_1.CustomNodes.BinaryExpressionFunctionNode); + binaryExpressionFunctionCustomNode.initialize(binaryExpressionNode.operator); + storageKey = RandomGeneratorUtils_1.RandomGeneratorUtils.getRandomString(3); + storageKeysByBinaryOperator.set(binaryExpressionNode.operator, [storageKey]); + this.binaryOperatorsDataByControlFlowStorageId.set(controlFlowStorageId, storageKeysByBinaryOperator); + controlFlowStorage.set(storageKey, binaryExpressionFunctionCustomNode); } - controlFlowStorageCallNode.initialize(controlFlowStorageCustomNodeName, key, BinaryExpressionControlFlowReplacer_1.getExpressionValue(binaryExpressionNode.left), BinaryExpressionControlFlowReplacer_1.getExpressionValue(binaryExpressionNode.right)); - var statementNode = controlFlowStorageCallNode.getNode()[0]; + controlFlowStorageCallCustomNode.initialize(controlFlowStorageId, storageKey, NodeUtils_1.NodeUtils.convertStructureToCode([binaryExpressionNode.left]), NodeUtils_1.NodeUtils.convertStructureToCode([binaryExpressionNode.right])); + var statementNode = controlFlowStorageCallCustomNode.getNode()[0]; if (!statementNode || !Node_1.Node.isExpressionStatementNode(statementNode)) { - throw new Error("`controlFlowStorageCallCustomNode.getNode()` should returns array with `ExpressionStatement` node"); + throw new Error("`controlFlowStorageCallNode.getNode()[0]` should returns array with `ExpressionStatement` node"); } return statementNode.expression; } }], [{ - key: "getExpressionValue", - value: function getExpressionValue(expressionNode) { - return escodegen.generate(expressionNode, { - sourceMapWithCode: true - }).code; + key: "getStorageKeysByBinaryOperatorForCurrentStorage", + value: function getStorageKeysByBinaryOperatorForCurrentStorage(binaryOperatorsDataByControlFlowStorageId, controlFlowStorageId) { + var storageKeysByBinaryOperator = void 0; + if (binaryOperatorsDataByControlFlowStorageId.has(controlFlowStorageId)) { + storageKeysByBinaryOperator = binaryOperatorsDataByControlFlowStorageId.get(controlFlowStorageId); + } else { + storageKeysByBinaryOperator = new Map(); + } + return storageKeysByBinaryOperator; } }]); @@ -5632,7 +5618,7 @@ var class_validator_1 = __webpack_require__(116); var DefaultPreset_1 = __webpack_require__(30); var OptionsNormalizer_1 = __webpack_require__(85); var ValidationErrorsFormatter_1 = __webpack_require__(86); -var Options_1 = function Options(inputOptions) { +var Options = Options_1 = function Options(inputOptions) { _classCallCheck(this, Options); Object.assign(this, DefaultPreset_1.DEFAULT_PRESET, inputOptions); @@ -5642,42 +5628,41 @@ var Options_1 = function Options(inputOptions) { } Object.assign(this, OptionsNormalizer_1.OptionsNormalizer.normalizeOptions(this)); }; -var Options = Options_1; Options.validatorOptions = { validationError: { target: false } }; -__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "compact", void 0); -__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "controlFlowFlattening", void 0); -__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "debugProtection", void 0); -__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "debugProtectionInterval", void 0); -__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "disableConsoleOutput", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "compact", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "controlFlowFlattening", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "debugProtection", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "debugProtectionInterval", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "disableConsoleOutput", void 0); __decorate([class_validator_1.IsArray(), class_validator_1.ArrayUnique(), class_validator_1.IsString({ each: true -}), __metadata('design:type', Array)], Options.prototype, "domainLock", void 0); +}), __metadata("design:type", Array)], Options.prototype, "domainLock", void 0); __decorate([class_validator_1.IsArray(), class_validator_1.ArrayUnique(), class_validator_1.IsString({ each: true -}), __metadata('design:type', Array)], Options.prototype, "reservedNames", void 0); -__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "rotateStringArray", void 0); -__decorate([class_validator_1.IsNumber(), __metadata('design:type', Number)], Options.prototype, "seed", void 0); -__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "selfDefending", void 0); -__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "sourceMap", void 0); +}), __metadata("design:type", Array)], Options.prototype, "reservedNames", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "rotateStringArray", void 0); +__decorate([class_validator_1.IsNumber(), __metadata("design:type", Number)], Options.prototype, "seed", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "selfDefending", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "sourceMap", void 0); __decorate([class_validator_1.IsString(), class_validator_1.ValidateIf(function (options) { return Boolean(options.sourceMapBaseUrl); }), class_validator_1.IsUrl({ require_protocol: true, require_valid_protocol: true -}), __metadata('design:type', String)], Options.prototype, "sourceMapBaseUrl", void 0); -__decorate([class_validator_1.IsString(), __metadata('design:type', String)], Options.prototype, "sourceMapFileName", void 0); -__decorate([class_validator_1.IsIn(['inline', 'separate']), __metadata('design:type', String)], Options.prototype, "sourceMapMode", void 0); -__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "stringArray", void 0); -__decorate([class_validator_1.IsIn([true, false, 'base64', 'rc4']), __metadata('design:type', Object)], Options.prototype, "stringArrayEncoding", void 0); -__decorate([class_validator_1.IsNumber(), class_validator_1.Min(0), class_validator_1.Max(1), __metadata('design:type', Number)], Options.prototype, "stringArrayThreshold", void 0); -__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "unicodeEscapeSequence", void 0); -Options = Options_1 = __decorate([inversify_1.injectable(), __metadata('design:paramtypes', [typeof (_a = typeof TInputOptions_1.TInputOptions !== 'undefined' && TInputOptions_1.TInputOptions) === 'function' && _a || Object])], Options); +}), __metadata("design:type", String)], Options.prototype, "sourceMapBaseUrl", void 0); +__decorate([class_validator_1.IsString(), __metadata("design:type", String)], Options.prototype, "sourceMapFileName", void 0); +__decorate([class_validator_1.IsIn(['inline', 'separate']), __metadata("design:type", String)], Options.prototype, "sourceMapMode", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "stringArray", void 0); +__decorate([class_validator_1.IsIn([true, false, 'base64', 'rc4']), __metadata("design:type", Object)], Options.prototype, "stringArrayEncoding", void 0); +__decorate([class_validator_1.IsNumber(), class_validator_1.Min(0), class_validator_1.Max(1), __metadata("design:type", Number)], Options.prototype, "stringArrayThreshold", void 0); +__decorate([class_validator_1.IsBoolean(), __metadata("design:type", Boolean)], Options.prototype, "unicodeEscapeSequence", void 0); +Options = Options_1 = __decorate([inversify_1.injectable(), __metadata("design:paramtypes", [Object])], Options); exports.Options = Options; -var _a; +var Options_1; /***/ }, /* 85 */ diff --git a/package.json b/package.json index a4359084..f0d1f19f 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "mocha": "3.2.0", "sinon": "2.0.0-pre.3", "ts-node": "1.7.2", - "tslint": "4.1.0", + "tslint": "4.1.1", "typescript": "2.1.4", "webpack": "2.1.0-beta.27", "webpack-node-externals": "1.5.4" diff --git a/src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts b/src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts index ea196ce9..b318b96a 100644 --- a/src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts +++ b/src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts @@ -8,8 +8,6 @@ import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { IOptions } from '../../../interfaces/options/IOptions'; import { IStorage } from '../../../interfaces/storages/IStorage'; -import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils'; - @injectable() export abstract class AbstractControlFlowReplacer implements IControlFlowReplacer { /** @@ -26,16 +24,6 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace this.options = options; } - /** - * @returns {string} - */ - protected static getStorageKey (): string { - return RandomGeneratorUtils.getRandomGenerator().string({ - length: 3, - pool: RandomGeneratorUtils.randomGeneratorPool - }); - } - /** * @param node * @param parentNode diff --git a/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts b/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts index 17933c64..7694291a 100644 --- a/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts +++ b/src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts @@ -1,7 +1,6 @@ import { injectable, inject } from 'inversify'; import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers'; -import * as escodegen from 'escodegen'; import * as ESTree from 'estree'; import { TCustomNodeFactory } from '../../../types/container/TCustomNodeFactory'; @@ -15,6 +14,7 @@ import { CustomNodes } from '../../../enums/container/CustomNodes'; import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer'; import { Node } from '../../../node/Node'; +import { NodeUtils } from '../../../node/NodeUtils'; import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils'; @injectable() @@ -25,9 +25,9 @@ export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowRepl private static readonly useExistingOperatorKeyThreshold: number = 0.5; /** - * @type {Map} + * @type {Map>} */ - private readonly existingBinaryExpressionKeys: Map = new Map (); + private readonly binaryOperatorsDataByControlFlowStorageId: Map > = new Map(); /** * @type {TCustomNodeFactory} @@ -48,20 +48,30 @@ export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowRepl } /** - * @param expressionNode - * @returns {string} + * @param binaryOperatorsDataByControlFlowStorageId + * @param controlFlowStorageId + * @returns {Map} */ - private static getExpressionValue (expressionNode: ESTree.Expression): string { - return escodegen.generate(expressionNode, { - sourceMapWithCode: true - }).code; + private static getStorageKeysByBinaryOperatorForCurrentStorage ( + binaryOperatorsDataByControlFlowStorageId: Map>, + controlFlowStorageId: string + ): Map { + let storageKeysByBinaryOperator: Map; + + if (binaryOperatorsDataByControlFlowStorageId.has(controlFlowStorageId)) { + storageKeysByBinaryOperator = >binaryOperatorsDataByControlFlowStorageId + .get(controlFlowStorageId); + } else { + storageKeysByBinaryOperator = new Map(); + } + + return storageKeysByBinaryOperator; } /** * @param binaryExpressionNode * @param parentNode * @param controlFlowStorage - * @param controlFlowStorageCustomNodeName * @returns {ESTree.Node} */ public replace ( @@ -69,44 +79,45 @@ export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowRepl parentNode: ESTree.Node, controlFlowStorage: IStorage ): ESTree.Node { - const controlFlowStorageCustomNodeName: string = controlFlowStorage.getStorageId(); - const binaryExpressionFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.BinaryExpressionFunctionNode); - const binaryExpressionOperatorKeys: { - [key: string]: string[] - } = this.existingBinaryExpressionKeys.get(controlFlowStorageCustomNodeName) || {}; - const controlFlowStorageCallNode: ICustomNode = this.customNodeFactory(CustomNodes.ControlFlowStorageCallNode); + const controlFlowStorageId: string = controlFlowStorage.getStorageId(); + const controlFlowStorageCallCustomNode: ICustomNode = this.customNodeFactory(CustomNodes.ControlFlowStorageCallNode); + const storageKeysByBinaryOperator: Map = BinaryExpressionControlFlowReplacer + .getStorageKeysByBinaryOperatorForCurrentStorage( + this.binaryOperatorsDataByControlFlowStorageId, + controlFlowStorageId + ); - let key: string = AbstractControlFlowReplacer.getStorageKey(); - - if (!binaryExpressionOperatorKeys[binaryExpressionNode.operator]) { - binaryExpressionOperatorKeys[binaryExpressionNode.operator] = []; - } - - binaryExpressionFunctionNode.initialize(binaryExpressionNode.operator); + let storageKeysForCurrentOperator: string[] | undefined = storageKeysByBinaryOperator.get(binaryExpressionNode.operator); + let storageKey: string; if ( RandomGeneratorUtils.getRandomFloat(0, 1) > BinaryExpressionControlFlowReplacer.useExistingOperatorKeyThreshold && - binaryExpressionOperatorKeys[binaryExpressionNode.operator].length + storageKeysForCurrentOperator && + storageKeysForCurrentOperator.length ) { - key = RandomGeneratorUtils.getRandomGenerator() - .pickone(binaryExpressionOperatorKeys[binaryExpressionNode.operator]); + storageKey = RandomGeneratorUtils.getRandomGenerator().pickone(storageKeysForCurrentOperator); } else { - binaryExpressionOperatorKeys[binaryExpressionNode.operator].push(key); - this.existingBinaryExpressionKeys.set(controlFlowStorageCustomNodeName, binaryExpressionOperatorKeys); - controlFlowStorage.set(key, binaryExpressionFunctionNode); + const binaryExpressionFunctionCustomNode: ICustomNode = this.customNodeFactory(CustomNodes.BinaryExpressionFunctionNode); + + binaryExpressionFunctionCustomNode.initialize(binaryExpressionNode.operator); + + storageKey = RandomGeneratorUtils.getRandomString(3); + storageKeysByBinaryOperator.set(binaryExpressionNode.operator, [storageKey]); + this.binaryOperatorsDataByControlFlowStorageId.set(controlFlowStorageId, storageKeysByBinaryOperator); + controlFlowStorage.set(storageKey, binaryExpressionFunctionCustomNode); } - controlFlowStorageCallNode.initialize( - controlFlowStorageCustomNodeName, - key, - BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.left), - BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.right) + controlFlowStorageCallCustomNode.initialize( + controlFlowStorageId, + storageKey, + NodeUtils.convertStructureToCode([binaryExpressionNode.left]), + NodeUtils.convertStructureToCode([binaryExpressionNode.right]) ); - const statementNode: TStatement = controlFlowStorageCallNode.getNode()[0]; + const statementNode: TStatement = controlFlowStorageCallCustomNode.getNode()[0]; if (!statementNode || !Node.isExpressionStatementNode(statementNode)) { - throw new Error(`\`controlFlowStorageCallCustomNode.getNode()\` should returns array with \`ExpressionStatement\` node`); + throw new Error(`\`controlFlowStorageCallNode.getNode()[0]\` should returns array with \`ExpressionStatement\` node`); } return statementNode.expression; diff --git a/test/dev/dev.ts b/test/dev/dev.ts index d25a77c3..5307d3d8 100644 --- a/test/dev/dev.ts +++ b/test/dev/dev.ts @@ -1,5 +1,4 @@ 'use strict'; -import { NO_CUSTOM_NODES_PRESET } from '../../src/preset-options/NoCustomNodesPreset'; if (!(global)._babelPolyfill) { require('babel-polyfill'); @@ -11,18 +10,78 @@ if (!(global)._babelPolyfill) { let obfuscatedCode: string = JavaScriptObfuscator.obfuscate( ` (function(){ + var result = 1, + term1 = 0, + term2 = 1, + i = 1; + while(i < 10) + { + var test = 10; + result = term1 + term2; + console.log(result); + term1 = term2; + term2 = result; + i++; + } + + console.log(test); + + var test = function (test) { + console.log(test); + + if (true) { + var test = 5 + } + + return test; + } + + console.log(test(1)); + + function test2 (abc) { + function test1 () { + console.log('inside', abc.item); + } + + console.log('ั‚ะตัั‚', abc); + + var abc = {}; + + return abc.item = 15, test1(); + }; + + var regexptest = /version\\/(\\d+)/i; + console.log(regexptest); + + test2(22); + console.log(105.4); + console.log(true, false); + + var sA = 'shorthand1'; + var sB = 'shorthand2'; + + console.log({sA, sB}); + + try { + } catch (error) { + console.log(error); + } + function foo () { return function () { - var sum = 1 + 2; - var sum = 3 + 4; - var sum = 5 + 6; - var sum = 8 - 6; + var sum1 = 10 + 20; + var sum2 = 20 + 30; + var sum3 = 30 + 50; + var sub = sum3 - sum2; + + return sum1 + sub; } } + + console.log(foo()()); })(); `, { - ...NO_CUSTOM_NODES_PRESET, compact: false, controlFlowFlattening: true, disableConsoleOutput: false diff --git a/test/unit-tests/node/NodeUtils.spec.ts b/test/unit-tests/node/NodeUtils.spec.ts index af1935a2..5dec1553 100644 --- a/test/unit-tests/node/NodeUtils.spec.ts +++ b/test/unit-tests/node/NodeUtils.spec.ts @@ -63,6 +63,29 @@ describe('NodeUtils', () => { }); }); + describe('convertStructureToCode (structure: ESTree.Node[]): string', () => { + let structure: ESTree.Node[], + expectedCode: string; + + beforeEach(() => { + structure = [ + NodeMocks.getProgramNode([ + NodeMocks.getVariableDeclarationNode([ + NodeMocks.getVariableDeclaratorNode( + NodeMocks.getIdentifierNode('abc'), + NodeMocks.getLiteralNode('cde') + ) + ]) + ]) + ]; + expectedCode = 'var abc = \'cde\';'; + }); + + it('should convert `ESTree.Node[]` structure to source code', () => { + assert.deepEqual(NodeUtils.convertStructureToCode(structure), expectedCode); + }); + }); + describe('getBlockStatementNodeByIndex (node: ESTree.Node, index: number = 0): ESTree.Node', () => { let blockStatementNode: ESTree.BlockStatement, expressionStatementNode1: ESTree.ExpressionStatement,