ソースを参照

StackTraceAnalyzer - correct analyzing of self-invoking functions

sanex3339 8 年 前
コミット
6c4eab9104

+ 6 - 4
dist/index.js

@@ -88,7 +88,7 @@ module.exports =
 /******/ 	__webpack_require__.p = "";
 /******/
 /******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(__webpack_require__.s = 81);
+/******/ 	return __webpack_require__(__webpack_require__.s = 80);
 /******/ })
 /************************************************************************/
 /******/ ([
@@ -3685,12 +3685,15 @@ var FunctionExpressionCalleeDataExtractor = function () {
             if (Nodes_1.Nodes.isIdentifierNode(this.callee)) {
                 calleeBlockStatement = this.getCalleeBlockStatement(NodeUtils_1.NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]), this.callee.name);
             }
+            if (Nodes_1.Nodes.isFunctionExpressionNode(this.callee)) {
+                calleeBlockStatement = this.callee.body;
+            }
             if (!calleeBlockStatement) {
                 return null;
             }
             return {
                 callee: calleeBlockStatement,
-                name: this.callee.name
+                name: this.callee.name || null
             };
         }
     }, {
@@ -3912,8 +3915,7 @@ module.exports = require("fs");
 module.exports = require("mkdirp");
 
 /***/ },
-/* 80 */,
-/* 81 */
+/* 80 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";

+ 1 - 1
src/interfaces/stack-trace-analyzer/ICalleeData.d.ts

@@ -2,5 +2,5 @@ import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
 
 export interface ICalleeData {
     callee: TNodeWithBlockStatement;
-    name: string;
+    name: string | null;
 }

+ 5 - 1
src/stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts

@@ -42,13 +42,17 @@ export class FunctionExpressionCalleeDataExtractor implements ICalleeDataExtract
             );
         }
 
+        if (Nodes.isFunctionExpressionNode(this.callee)) {
+            calleeBlockStatement = this.callee.body;
+        }
+
         if (!calleeBlockStatement) {
             return null;
         }
 
         return {
             callee: calleeBlockStatement,
-            name: this.callee.name
+            name: this.callee.name || null
         };
     }
 

+ 9 - 0
test/fixtures/stack-trace-analyzer/self-invoking-functions.js

@@ -0,0 +1,9 @@
+(function foo (){
+    (function bar (){
+        baz();
+
+        function baz () {
+
+        }
+    }());
+})();

+ 53 - 0
test/functional-tests/stack-trace-analyzer/StackTraceAnalyzer.spec.ts

@@ -66,6 +66,32 @@ function getFunctionExpressionByName (astTree: ESTree.Node, name: string): ESTre
     return functionExpressionNode;
 }
 
+/**
+ * @param astTree
+ * @param id
+ * @returns {ESTree.FunctionExpression|null}
+ */
+function getFunctionExpressionById (astTree: ESTree.Node, id: string): ESTree.FunctionExpression|null {
+    let functionExpressionNode: ESTree.FunctionExpression|null = null;
+
+    estraverse.traverse(astTree, {
+        enter: (node: ESTree.Node): any => {
+            if (
+                Nodes.isFunctionExpressionNode(node) &&
+                node.id &&
+                Nodes.isIdentifierNode(node.id) &&
+                node.id.name === id
+            ) {
+                functionExpressionNode = node;
+
+                return estraverse.VisitorOption.Break;
+            }
+        }
+    });
+
+    return functionExpressionNode;
+}
+
 describe('StackTraceAnalyzer', () => {
     describe('extract (): IStackTraceData[]', () => {
         let astTree: TNodeWithBlockStatement,
@@ -245,5 +271,32 @@ describe('StackTraceAnalyzer', () => {
 
             assert.deepEqual(stackTraceData, expectedStackTraceData);
         });
+
+        it('should returns correct BlockScopeTraceData - variant #8: self-invoking functions', () => {
+            astTree = <ESTree.Program>NodeUtils.convertCodeToStructure(
+                readFileAsString('./test/fixtures/stack-trace-analyzer/self-invoking-functions.js'),
+                false
+            );
+
+            expectedStackTraceData = [
+                {
+                    name: null,
+                    callee: (<ESTree.FunctionExpression>getFunctionExpressionById(astTree, 'foo')).body,
+                    stackTrace: [{
+                        name: null,
+                        callee: (<ESTree.FunctionExpression>getFunctionExpressionById(astTree, 'bar')).body,
+                        stackTrace: [{
+                            name: 'baz',
+                            callee: (<ESTree.FunctionDeclaration>getFunctionDeclarationByName(astTree, 'baz')).body,
+                            stackTrace: []
+                        }]
+                    }]
+                }
+            ];
+
+            stackTraceData = new StackTraceAnalyzer(astTree.body).analyze();
+
+            assert.deepEqual(stackTraceData, expectedStackTraceData);
+        });
     });
 });