All files / vsl/resolver/resolvers literalResolver.js

0% Statements 0/17
0% Branches 0/11
0% Functions 0/2
0% Lines 0/17
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                                                                                                                                                   
import ConstraintType from '../constraintType';
import TypeConstraint from '../typeConstraint';
import TypeResolver from '../typeResolver';
 
// import STL from '../../stl/stl';
 
import VSLTokenType from '../../parser/vsltokentype.js';
 
/**
 * Resolves any atomic literal described by an `Literal` token class.
 */
export default class LiteralResolver 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
    ) {
        super(node, getChild);
    }
    
    /**
     * 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 {
        // Check the requested types of this ID
        const response = negotiate(ConstraintType.RequestedTypeResolutionConstraint);
        
        // Specify default types for the candidates
        // Perhaps in the future a STL item would have to register or request
        // to be a default candidate but for now they are hardcoded here
        switch (this.node.type) {
            case VSLTokenType.Integer:
                this.node.typeCandidates = [STL.Int, STL.Float, STL.Double]
                break;
                
            case VSLTokenType.Decimal:
                this.node.typeCandidates = [STL.Float, STL.Double]
                break;
                
            case VSLTokenType.String:
                this.node.typeCandidates = [STL.String]
                break;
                
            case VSLTokenType.Regex:
                break;
                
            default: throw new TypeError(`Undeducatble literal of type ${this.node.type}`);
        }
        
        if (response !== null) {
            this.node.typeCandidates = this.node.typeCandidates.filter(::response.includes)
        }
        
        if (this.node.typeCandidates.length === 0) {
            throw new Error(`Literal has no overlapping type candidates`);
        }
        
        if (this.node.typeCandidates.length === 1) {
            this.node.exprType = this.node.typeCandidates[0];
        }
    }
}