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

100% Statements 21/21
100% Branches 8/8
100% Functions 1/1
100% Lines 18/18

    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
    601x

    1x

    1x
    1x
    1x

    1x

    10416x

    10416x
    2185x

    10416x
    9298x

    1118x

    2185x

    2185x

    153831x
    1118x

    1118x

    2185x

     import { injectable } from 'inversify';

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

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

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

    @injectable()
    export class FunctionDeclarationCalleeDataExtractor extends AbstractCalleeDataExtractor {
        /**
         * @param blockScopeBody
         * @param callee
         * @returns {ICalleeData|null}
         */
        public extract (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier): ICalleeData|null {
            let calleeBlockStatement: ESTree.BlockStatement|null = null;

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

            if (!calleeBlockStatement) {
                return null;
            }

            return {
                callee: calleeBlockStatement,
                name: callee.name
            };
        }

        /**
         * @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): any => {
                    if (Node.isFunctionDeclarationNode(node) && node.id.name === name) {
                        calleeBlockStatement = node.body;

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

            return calleeBlockStatement;
        }
    }