<commit_before>/**
 * Extensions of CFG
 * Created by chengfulin on 2015/4/15.
 */
var esgraph = require('esgraph'),
    esprima = require('esprima'),
    walkes = require('walkes'),
    namespace = require('./namespace'),
    internal = namespace();

/**
 * Extended for CFG build by esgraph
 * @constructor
 */
function CFGExt() {
    'use strict';
    internal(this).lastId = -1;
}

/**
 * Parse the code to AST with default range option
 * @param code source code
 * @returns {*}
 */
CFGExt.prototype.parseAST = function parseAST(code) {
    'use strict';
    return esprima.parse(code, {range: true});
};

/**
 * Get the CFG of the AST
 * @param ast
 * @returns {Array} CFG
 */
CFGExt.prototype.getCFG = function getCFG(ast) {
    'use strict';
    var cfg = esgraph(ast);
    for(var index = 0; index < cfg[2].length; ++index) {
        (cfg[2][index]).cfgId = internal(this).lastId + index + 1;
    }
    internal(this).lastId += cfg[2].length;
    return cfg;
};

/**
 * Find function scopes of AST parsed from source
 * @param ast
 * @returns {Array}<commit_msg>Add label when get CFG<commit_after>/**
 * Extensions of CFG
 * Created by chengfulin on 2015/4/15.
 */
var esgraph = require('esgraph'),
    esprima = require('esprima'),
    walkes = require('walkes'),
    namespace = require('./namespace'),
    internal = namespace();

/**
 * Extended for CFG build by esgraph
 * @constructor
 */
function CFGExt() {
    'use strict';
    internal(this).lastId = -1;
}

/**
 * Parse the code to AST with default range option
 * @param code source code
 * @returns {*}
 */
CFGExt.prototype.parseAST = function parseAST(code) {
    'use strict';
    return esprima.parse(code, {range: true});
};

/**
 * Get the CFG of the AST with additional information
 * @param ast
 * @returns {Array} CFG
 */
CFGExt.prototype.getCFG = function getCFG(ast) {
    'use strict';
    var cfg = esgraph(ast);
    /// Add cfgId and label to each node
    for(var index = 0; index < cfg[2].length; ++index) {
        (cfg[2][index]).cfgId = internal(this).lastId + index + 1;
        (cfg[2][index]).label = (cfg[2][index]).cfgId;
    }
    /// label for entry and exit node
    cfg[0].label = 'entry';
    cfg[1].label = 'exit';
    internal(this).lastId += cfg[2].length;
    return cfg;
};

/**
 * Find function scopes of AST parsed from source
 * @param ast
 * @returns {Array}
{'fraction_non_alphanumeric': 0.15878378378378377, 'fraction_numerical': 0.01266891891891892, 'mean_word_length': 3.0986159169550174, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5959628', 'n_tokens_mistral': 796, 'n_tokens_neox': 772, 'n_words': 227}