All files / parser/nodes node.js

16.67% Statements 5/30
5.26% Branches 1/19
25% Functions 1/4
16.67% Lines 5/30
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98                  2030x 2030x               2030x               2030x                         2030x                                                                                                                    
/**
 * Node class for AST.
 */
export default class Node {
    
    /**
     * Creates a new Node object.
     */
    constructor(position: Object) {
        Eif (process.env["VSL_ENV"] != "dev_debug")
            this.position = position;
        
        /**
         * If exists, references the closest scope. Use an ASTTool to perform
         * variable lookups
         * 
         * @type {?CodeBlock}
         */
        this.parentScope = null;
        
        /**
         * If exists, a traverser will set this to the parent node or wrapping
         * container.
         * 
         * @type {?(Node | Node[])}
         */
        this.parentNode = null;
        
        /**
         * An integer representing the position within a queue to qualify the
         * node for a GC pass when requested by a parent.
         * 
         * A {@link Transformer} will automatically do this.
         * 
         * If you set this, the ASTTool for the node should process with a
         * transformer.
         * 
         * @type {?number}
         */
        this.queueQualifier = null;
    }
    
    /**
     * Generates an string representing the AST from a generator.
     * 
     * The string should use the passed generator to create the outputting
     * string so padding is correct.
     * 
     * @abstract
     * @param {Generator} generator the target generator
     **/
     generate(generator: Generator) {
         throw new TypeError("generate(generator:) must be overriden");
     }
    
    /**
     * Returns all the children of a node. The order must be consistent
     * @type {?Node[]}
     */
    get children() {
        throw new Error("Must implement Node#children");
    }
    
    /**
     * Returns the string representation of the Node.
     * @param {string} padding String to add to the left of the tree
     * @return {string} Tree representation of this node.
     */
    toAST (padding: String='') {
        let children = this.children;
        if (this.unbox)
            return padding + '"' + this.children + '"\n';
        let result = '';
        if (this.type === NodeType.BinaryExpression || this.type === NodeType.UnaryExpression)
            result = result + padding + operator_names[this.operator_type] + '\n';
        else
            result = result + padding + this.constructor.name + '\n';
        if (padding.length >= 3) {
            let last_chars = padding.slice(-1);
            if (last_chars === '├')
                padding = padding.slice(0, -1) + '│';
            else if (last_chars === '└')
                padding = padding.slice(0, -1) + ' ';
        }
        if (typeof this.children === 'string')
            result = result + padding + '└"' + this.children + '"\n';
        else if (this.children.length !== 0) {
            let new_padding = padding + '├';
            for (let i = 0; i < this.children.length - 1; i++)
                result += this.children[i].toAST(new_padding);
            new_padding = padding + '└';
            let item = this.children[this.children.length - 1];
            result += item.toAST(new_padding);
        }
        return result;
    }
    
}