All files / transform transformation.js

66.67% Statements 2/3
100% Branches 0/0
50% Functions 1/2
66.67% Lines 2/3
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 99 100 101                                                                                                                                228x   228x                                                                    
/**
 * A transformation or a pass for a `Transformer`
 * 
 * ### Usage
 * 
 * Subclass this and pass it to a `Transformer` to apply it to an AST. Each is
 * passed a `ASTTool` object to aid in modifying and traversing the AST. Never
 * use anything but the ASTTool for modification. Additionally do not attempt to
 * use any undocumented methods of `ASTTool`, as.
 * 
 * Override:
 *  - The constructor to provide the node type to run the transformation upon
 *     and the transformation's name.
 *  - The `modify(node:tool:)` method of this class.
 * 
 * Refer to the {@link ASTTool} reference for further information.
 * 
 * ### Information
 * 
 * A transformation is loaded into a transformer and it automatically called
 * where applicable. A transformer should not queue or delegate any further
 * nodes to transformation, nor should it attempt to mutate the AST without the
 * use of an ASTTool.
 * 
 * ### Timing
 * 
 * Each Transformation is individually timed and tracked by a {@link Transformer}. The
 * timing information is obtained through the `transform(ast:parent:)` method for
 * any and all routed transformations. It is available accurate to microsecond
 * precision and should be used for all transformations to ensure the most efficient
 * transformations are occuring.
 * 
 * Transformations are recursive any may run on replaced nodes if the transformer
 * deems correct. You may need to specify specifically if your Transformation
 * requests specific queuing priority or transformation status to avoid extra runs
 * and calls.
 * 
 * @example
 * import Transformation from '../transformation';
 * import TokenType from '../../parser/vsltokentype';
 * import t from '../../parser/nodes';
 * 
 * export default class MyTransformer extends Transformation {
 *     constructor() {
 *          super(t.Expression, "TransformerType::TransformerName");
 *     }
 * 
 *     modify(node: Node, tool: ASTTool) {
 *         // ... modifications
 *         tool.replace( newNode );
 *     }
 * }
 * 
 * @abstract
 */
export default class Transformation {
    /**
     * Creates a new transformation object
     * 
     * @param {Class<Node>} type - the node type to match which is subclass of Node
     * @param {string} name - the name of the transformation object, for debug purposes
     */
    constructor(type: Class<Node>, name: any) {
        /** @type {Class<Node>} */
        this.type = type;
        /** @type {string} */
        this.name = name;
    }
    
    /**
     * Modifies a given AST fragment with the `tool`.
     * 
     * This is the primary function which you must implement to create a
     * transformer. You can specifically specify the node type this executes upon
     * through specifying the "type" field in the `super` call within your
     * constructor.
     * 
     * To run upon any time, pass `null` to the constructor. Never pass undefined
     * to a field unless specifically noted. If you do happen to pass null you
     * must perform type checking yourself by using `instanceof` with a node type.
     * 
     * You likely need access to the node classes to check if a node is of a
     * specific type, you can import this using:
     * 
     *      import t from '../../parser/nodes';
     * 
     * This file is automatically updated based on the directory contents at
     * build-time.
     * 
     * This methods execution shuold generally be controlled by a `Transformer`
     * or a seperate parent object to interface with the delegates.
     * 
     * @param {Node} node - The node being applied on
     * @param {ASTTool} tool - The ASTTool for modifications
     * 
     * @abstract
     */
    modify(node: Node, tool: ASTTool) {
        throw new TypeError("Must overload Transformation#modify(node, tool)");
    }
}