# all files / files/ JavaScriptFile.js

100% Statements 130/130
100% Branches 63/63
100% Functions 20/20
100% Lines 28/28
37 statements, 1 function, 29 branches Ignored

    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

    1
    1
    1
    1
    1

    4

    3

    1
    1

    5
    3

    5
    3
    3

    5

    1
    1

    1
    7
    8
    1

    1
    7
    4

    7

    1
    7

     'use strict';

    // Constants:
    import constants from '../constants';
    const LEADING_SLASH_REGEX = /^\//;
    const TRAILING_SLASH_REGEX = /(\/)[gimuy]*?$/;
    const REGEXP_CONTENT_REGEX = /^\/.*\/[gimuy]*?$/;
    const REGEXP_FLAGS_REGEX = /([gimuy]*)$/;
    const LITERAL = 'Literal';

    // Utilities:
    import _ from 'lodash';

    // Dependencies:
    import escodegen from 'escodegen';
    import esprima from 'esprima';
    import File from './File';

    // Errors:
    import TractorError from '../errors/TractorError';

    export default class JavaScriptFile extends File {
        read () {
            return super.read()
            .then(() => {
                this.ast = esprima.parse(this.content, {
                    comment: true
                });
            })
            .catch((error) => {
                console.error(error);
                throw new TractorError(`Parsing "${this.path}" failed.`, constants.REQUEST_ERROR);
            });
        }

        save (data) {
            if (data) {
                this.ast = data;
            }
            if (this.ast) {
                this.ast.leadingComments = this.ast.comments;
                this.content = escodegen.generate(rebuildRegExps(this.ast), {
                    comment: true
                });
            }

            return super.save()
            .catch((error) => {
                console.error(error);
                throw new TractorError(`Saving "${this.path}" failed.`, constants.REQUEST_ERROR);
            });
        }
    }

    function rebuildRegExps (object) {
        _.each(object, (value) => {
            if (value && isRegexLiteral(value)) {
                let regexContent = value.raw
                .replace(LEADING_SLASH_REGEX, '')
                .replace(TRAILING_SLASH_REGEX, '');
                let [regexFlags] = REGEXP_FLAGS_REGEX.exec(value.raw);
                value.value = new RegExp(regexContent, regexFlags);
            } else if (_.isArray(value) || _.isObject(value)) {
                rebuildRegExps(value);
            }
        });
        return object;
    }

    function isRegexLiteral (object) {
        return object.type === LITERAL
            && object.raw
            && REGEXP_CONTENT_REGEX.test(object.raw);
    }