StackTraceAnalyzer - correct analyzing of self-invoking functions

This commit is contained in:
sanex3339
2016-10-06 14:41:46 +03:00
parent 32418387bf
commit 6c4eab9104
5 changed files with 74 additions and 6 deletions
+6 -4
View File
@@ -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
View File
@@ -2,5 +2,5 @@ import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
export interface ICalleeData {
callee: TNodeWithBlockStatement;
name: string;
name: string | null;
}
@@ -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
};
}
@@ -0,0 +1,9 @@
(function foo (){
(function bar (){
baz();
function baz () {
}
}());
})();
@@ -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);
});
});
});