All files / resolver/resolvers rootResolver.js

0% Statements 0/12
0% Branches 0/3
0% Functions 0/3
0% Lines 0/12
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                                                                                                                         
import ConstraintType from '../constraintType';
import TypeConstraint from '../typeConstraint';
import TypeResolver from '../typeResolver';
 
/**
 * Resolves `ExpressionStatement`s at the top level. This class only takes in a
 * single `ContextParentConstraint`. For functions this would probably needed to
 * be propogated to take into scope and resolve which function prototypes fit
 * the bill.
 * 
 * Call this if you have an expression you want to resolve and DO NOT FORGET
 * to specify a negotiator. Make sure your negotiator is damn good for best
 * results.
 */
export default class RootResolver extends TypeResolver {
    
    /**
     * @param {Node} node - The node to resolve.
     * @param {function(from: Node): TypeResolver} getChild - Takes a node and
     *     returns the resolver to execute, it is reccomended to just use a
     *     `switch` statement with `from.constructor` and then use that. It is
     *     fine to throw if the node is unhandled.
     */
    constructor(
        node: Node,
        getChild: (Node) => TypeResolver,
        context: ?TransformationContext
    ) {
        super(node, getChild);
        this.context = context;
    }
    
    /**
     * Resolves types for a given node.
     * 
     * @param {function(offer: ConstraintType): ?TypeConstraint} negotiate - The
     *     function which will handle or reject all negotiation requests. Use
     *     `{ nil }` to reject all offers (bad idea though).
     */
 
    resolve(negotiate: (ConstraintType) => ?TypeConstraint): void {
        // Attempt to obtain any context-clues/types
        // example: `var a: T = b`
        // `b` is an ExpressionStatement, `T` is what this would give
        const response = negotiate(ConstraintType.ContextParentConstraint);
        const negotiator = (type) => {
            switch (type) {
                case ConstraintType.ContextParentConstraint: return response;
                case ConstraintType.TransformationContext: return this.context;
                default: return null;
            }
        };
        
        const child = this.getChild(this.node.expression);
        child.resolve(negotiator);
        
        this.node.typeCandidates = this.node.expression.typeCandidates;
        this.node.exprType = this.node.expression.exprType;
    }
}