Code coverage report for src/stack-trace-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts

# All files / src/stack-trace-analyzer/callee-data-extractors FunctionExpressionCalleeDataExtractor.ts

100% Statements 20/20
100% Branches 14/14
100% Functions 2/2
100% Lines 20/20

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    831x

    1x
    1x

    1x

    15786x
    15786x

    15786x

    15786x
    5224x

    15786x
    1571x

    15786x
    12648x

    3138x

    5224x

    5224x

    388591x

    1567x

    1567x

    5224x

     import * as estraverse from 'estraverse';
    import * as ESTree from 'estree';

    import { ICalleeData } from '../../interfaces/stack-trace-analyzer/ICalleeData';
    import { ICalleeDataExtractor } from '../../interfaces/stack-trace-analyzer/ICalleeDataExtractor';

    import { Node } from '../../node/Node';
    import { NodeUtils } from '../../node/NodeUtils';

    export class FunctionExpressionCalleeDataExtractor implements ICalleeDataExtractor {
        /**
         * @type {ESTree.Node[]}
         */
        private blockScopeBody: ESTree.Node[];

        /**
         * @type {ESTree.Identifier}
         */
        private callee: ESTree.Identifier;

        /**
         * @param blockScopeBody
         * @param callee
         */
        constructor (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier) {
            this.blockScopeBody = blockScopeBody;
            this.callee = callee;
        }

        /**
         * @returns {ICalleeData|null}
         */
        public extract (): ICalleeData|null {
            let calleeBlockStatement: ESTree.BlockStatement|null = null;

            if (Node.isIdentifierNode(this.callee)) {
                calleeBlockStatement = this.getCalleeBlockStatement(
                    NodeUtils.getBlockScopeOfNode(this.blockScopeBody[0]),
                    this.callee.name
                );
            }

            if (Node.isFunctionExpressionNode(this.callee)) {
                calleeBlockStatement = this.callee.body;
            }

            if (!calleeBlockStatement) {
                return null;
            }

            return {
                callee: calleeBlockStatement,
                name: this.callee.name || null
            };
        }

        /**
         * @param node
         * @param name
         * @returns {ESTree.BlockStatement|null}
         */
        private getCalleeBlockStatement (node: ESTree.Node, name: string): ESTree.BlockStatement|null {
            let calleeBlockStatement: ESTree.BlockStatement|null = null;

            estraverse.traverse(node, {
                enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
                    if (
                        Node.isFunctionExpressionNode(node) &&
                        Node.isVariableDeclaratorNode(parentNode) &&
                        Node.isIdentifierNode(parentNode.id) &&
                        parentNode.id.name === name
                    ) {
                        calleeBlockStatement = node.body;

                        return estraverse.VisitorOption.Break;
                    }
                }
            });

            return calleeBlockStatement;
        }
    }