瀏覽代碼

binary expression replacer algorithm update wip

sanex3339 8 年之前
父節點
當前提交
d610534575

+ 19 - 2
dist/index.js

@@ -4215,6 +4215,9 @@ var FunctionControlFlowTransformer = FunctionControlFlowTransformer_1 = function
             }
             estraverse.replace(functionNode.body, {
                 enter: function enter(node, parentNode) {
+                    if (Math.random() > FunctionControlFlowTransformer_1.controlFlowReplacersThreshold) {
+                        return;
+                    }
                     var controlFlowReplacerName = FunctionControlFlowTransformer_1.controlFlowReplacersMap.get(node.type);
                     if (controlFlowReplacerName === undefined) {
                         return;
@@ -4282,6 +4285,7 @@ var FunctionControlFlowTransformer = FunctionControlFlowTransformer_1 = function
     return FunctionControlFlowTransformer;
 }(AbstractNodeTransformer_1.AbstractNodeTransformer);
 FunctionControlFlowTransformer.controlFlowReplacersMap = new Map([[NodeType_1.NodeType.BinaryExpression, NodeControlFlowReplacers_1.NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer]]);
+FunctionControlFlowTransformer.controlFlowReplacersThreshold = 0.75;
 FunctionControlFlowTransformer.hostNodeSearchMinDepth = 2;
 FunctionControlFlowTransformer.hostNodeSearchMaxDepth = 10;
 FunctionControlFlowTransformer = FunctionControlFlowTransformer_1 = __decorate([inversify_1.injectable(), __param(0, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers['Factory<IStorage<ICustomNode>>'])), __param(1, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers['Factory<IControlFlowReplacer>'])), __param(2, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers['Factory<ICustomNode>'])), __param(3, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers.IOptions)), __metadata("design:paramtypes", [Function, Function, Function, Object])], FunctionControlFlowTransformer);
@@ -4378,6 +4382,7 @@ 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 _ = __webpack_require__(34);
 var CustomNodes_1 = __webpack_require__(12);
 var AbstractControlFlowReplacer_1 = __webpack_require__(69);
 var Node_1 = __webpack_require__(4);
@@ -4389,6 +4394,7 @@ var BinaryExpressionControlFlowReplacer = BinaryExpressionControlFlowReplacer_1
 
         var _this = _possibleConstructorReturn(this, (BinaryExpressionControlFlowReplacer.__proto__ || Object.getPrototypeOf(BinaryExpressionControlFlowReplacer)).call(this, options));
 
+        _this.existingBinaryExpressionKeys = new Map();
         _this.customNodeFactory = customNodeFactory;
         return _this;
     }
@@ -4396,12 +4402,22 @@ var BinaryExpressionControlFlowReplacer = BinaryExpressionControlFlowReplacer_1
     _createClass(BinaryExpressionControlFlowReplacer, [{
         key: "replace",
         value: function replace(binaryExpressionNode, parentNode, controlFlowStorage, controlFlowStorageCustomNodeName) {
-            var key = AbstractControlFlowReplacer_1.AbstractControlFlowReplacer.getStorageKey();
             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 (Math.random() > BinaryExpressionControlFlowReplacer_1.useExistingOperatorKeyThreshold && binaryExpressionOperatorKeys[binaryExpressionNode.operator].length) {
+                key = _.sample(binaryExpressionOperatorKeys[binaryExpressionNode.operator]);
+            } else {
+                binaryExpressionOperatorKeys[binaryExpressionNode.operator].push(key);
+                this.existingBinaryExpressionKeys.set(controlFlowStorageCustomNodeName, binaryExpressionOperatorKeys);
+                controlFlowStorage.set(key, binaryExpressionFunctionNode);
+            }
             controlFlowStorageCallNode.initialize(controlFlowStorageCustomNodeName, key, BinaryExpressionControlFlowReplacer_1.getExpressionValue(binaryExpressionNode.left), BinaryExpressionControlFlowReplacer_1.getExpressionValue(binaryExpressionNode.right));
-            controlFlowStorage.set(key, binaryExpressionFunctionNode);
             var statementNode = controlFlowStorageCallNode.getNode()[0];
             if (!statementNode || !Node_1.Node.isExpressionStatementNode(statementNode)) {
                 throw new Error("`controlFlowStorageCallCustomNode.getNode()` should returns array with `ExpressionStatement` node");
@@ -4419,6 +4435,7 @@ var BinaryExpressionControlFlowReplacer = BinaryExpressionControlFlowReplacer_1
 
     return BinaryExpressionControlFlowReplacer;
 }(AbstractControlFlowReplacer_1.AbstractControlFlowReplacer);
+BinaryExpressionControlFlowReplacer.useExistingOperatorKeyThreshold = 0.5;
 BinaryExpressionControlFlowReplacer = BinaryExpressionControlFlowReplacer_1 = __decorate([inversify_1.injectable(), __param(0, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers['Factory<ICustomNode>'])), __param(1, inversify_1.inject(ServiceIdentifiers_1.ServiceIdentifiers.IOptions)), __metadata("design:paramtypes", [Function, Object])], BinaryExpressionControlFlowReplacer);
 exports.BinaryExpressionControlFlowReplacer = BinaryExpressionControlFlowReplacer;
 var BinaryExpressionControlFlowReplacer_1;

+ 9 - 0
src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts

@@ -35,6 +35,11 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
         [NodeType.BinaryExpression, NodeControlFlowReplacers.BinaryExpressionControlFlowReplacer]
     ]);
 
+    /**
+     * @type {number}
+     */
+    private static readonly controlFlowReplacersThreshold: number = 0.75;
+
     /**
      * @type {number}
      */
@@ -173,6 +178,10 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
 
         estraverse.replace(functionNode.body, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
+                if (Math.random() > FunctionControlFlowTransformer.controlFlowReplacersThreshold) {
+                    return;
+                }
+
                 const controlFlowReplacerName: NodeControlFlowReplacers | undefined = FunctionControlFlowTransformer
                     .controlFlowReplacersMap.get(node.type);
 

+ 32 - 3
src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts

@@ -3,6 +3,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
 
 import * as escodegen from 'escodegen';
 import * as ESTree from 'estree';
+import * as _ from 'lodash';
 
 import { TCustomNodeFactory } from '../../../types/container/TCustomNodeFactory';
 import { TStatement } from '../../../types/node/TStatement';
@@ -18,6 +19,16 @@ import { Node } from '../../../node/Node';
 
 @injectable()
 export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowReplacer {
+    /**
+     * @type {number}
+     */
+    private static readonly useExistingOperatorKeyThreshold: number = 0.5;
+
+    /**
+     * @type {Map<string, any>}
+     */
+    private readonly existingBinaryExpressionKeys: Map <string, any> = new Map <string, any> ();
+
     /**
      * @type {TCustomNodeFactory}
      */
@@ -59,11 +70,31 @@ export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowRepl
         controlFlowStorage: IStorage <ICustomNode>,
         controlFlowStorageCustomNodeName: string
     ): ESTree.Node {
-        const key: string = AbstractControlFlowReplacer.getStorageKey();
         const binaryExpressionFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.BinaryExpressionFunctionNode);
+        const binaryExpressionOperatorKeys: {
+            [key: string]: string[]
+        } = this.existingBinaryExpressionKeys.get(controlFlowStorageCustomNodeName) || {};
         const controlFlowStorageCallNode: ICustomNode = this.customNodeFactory(CustomNodes.ControlFlowStorageCallNode);
 
+        let key: string = AbstractControlFlowReplacer.getStorageKey();
+
+        if (!binaryExpressionOperatorKeys[binaryExpressionNode.operator]) {
+            binaryExpressionOperatorKeys[binaryExpressionNode.operator] = [];
+        }
+
         binaryExpressionFunctionNode.initialize(binaryExpressionNode.operator);
+
+        if (
+            Math.random() > BinaryExpressionControlFlowReplacer.useExistingOperatorKeyThreshold &&
+            binaryExpressionOperatorKeys[binaryExpressionNode.operator].length
+        ) {
+            key = _.sample(binaryExpressionOperatorKeys[binaryExpressionNode.operator]);
+        } else {
+            binaryExpressionOperatorKeys[binaryExpressionNode.operator].push(key);
+            this.existingBinaryExpressionKeys.set(controlFlowStorageCustomNodeName, binaryExpressionOperatorKeys);
+            controlFlowStorage.set(key, binaryExpressionFunctionNode);
+        }
+
         controlFlowStorageCallNode.initialize(
             controlFlowStorageCustomNodeName,
             key,
@@ -71,8 +102,6 @@ export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowRepl
             BinaryExpressionControlFlowReplacer.getExpressionValue(binaryExpressionNode.right)
         );
 
-        controlFlowStorage.set(key, binaryExpressionFunctionNode);
-
         const statementNode: TStatement = controlFlowStorageCallNode.getNode()[0];
 
         if (!statementNode || !Node.isExpressionStatementNode(statementNode)) {

+ 3 - 12
test/dev/dev.ts

@@ -14,18 +14,9 @@ if (!(<any>global)._babelPolyfill) {
                 function foo () {
                     return function () {
                         var sum = 1 + 2;
-                        
-                         function foo () {
-                            return function () {
-                                var sum = 1 - 2;
-                                
-                                 function foo () {
-                                    return function () {
-                                        var sum = 1 * 2;
-                                    }
-                                 }
-                            }
-                         }
+                        var sum = 3 + 4;
+                        var sum = 5 + 6;
+                        var sum = 8 - 6;
                     }
                 }
             })();