"use strict";

// Removes proxy rules -- that is, rules that only delegate to other rule.
function removeProxyRules( ast, session, options ) {

    function isProxyRule( node ) {

        return node.type === "rule" && node.expression.type === "rule_ref";

    }

    function replaceRuleRefs( ast, from, to ) {

        const replace = session.buildVisitor( {
            rule_ref( node ) {

                if ( node.name === from ) {

                    node.name = to;

                }

            }
        } );

        replace( ast );

    }

    const indices = [];

    ast.rules.forEach( ( rule, i ) => {

        if ( isProxyRule( rule ) ) {

            replaceRuleRefs( ast, rule.name, rule.expression.name );
            if ( options.allowedStartRules.indexOf( rule.name ) === -1 ) {

                indices.push( i );

            }

        }

    } );

    indices.reverse();

    indices.forEach( i => {

        ast.rules.splice( i, 1 );

    } );

}

module.exports = removeProxyRules;

"use strict";

// Removes proxy rules -- that is, rules that only delegate to other rule.
function removeProxyRules( ast, session, options ) {

    function isProxyRule( node ) {

        return node.type === "rule" && node.expression.type === "rule_ref";

    }

    const replaceRuleRefs = session.buildVisitor( {

        rule_ref( node, proxy, real ) {

            if ( node.name === proxy ) node.name = real;

        }

    } );

    const allowedStartRules = options.allowedStartRules;
    const rules = [];

    for ( const rule of ast.rules ) {

        if ( isProxyRule( rule ) ) {

            replaceRuleRefs( ast, rule.name, rule.expression.name );
            if ( allowedStartRules.indexOf( rule.name ) < 0 ) continue;

        }

        rules.push( rule );

    }

    ast.rules = rules;

}

module.exports = removeProxyRules;

Refactor removeProxyRules