All files / transform/passes DescribeVariableAssignment.js

6.25% Statements 1/16
0% Branches 0/6
50% Functions 1/2
6.67% Lines 1/15
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                          19x                                                                    
import Transformation from '../transformation';
import t from '../../parser/nodes';
 
import ScopeAliasItem from '../../scope/items/scopeAliasItem';
import ScopeTypeItem from '../../scope/items/scopeTypeItem';
 
/**
 * A pre-processing assignment value. So for `var x = a`. This will register
 * x as a type. Candidates will not be registered, that happens in the
 * transformer.
 */
export default class DescribeVariableAssignment extends Transformation {
    constructor() {
        super(t.AssignmentStatement, "Describe::VariableAssignment");
    }
    
    modify(node: Node, tool: ASTTool) {
        // Quite a mouth full but explanation:
        // Node (AssignmentStatement) -> TypedIdentifier -> Identifier -> ScopeItem -> String
        let rootId = node.identifier.identifier.identifier.rootId;
        
        let scope = node.parentScope.scope;
        
        // Resolve the type if applicable
        let candidates = [];
        if (node.identifier.type !== null) {
            tool.queueThenDeep(node.identifier.type, node.identifier, 'type', null);
            let type = node.identifier.type;
            
            if (!(type instanceof t.Identifier)) {
                throw new TypeError(`Did not reduce type, ${node.identifier}, to ID`);
            }
            
            let lookupId = type.identifier.rootId;
            // Locate type
            let candidate = scope.get(new ScopeTypeItem(lookupId));
            
            if (candidate === null) candidates.push(lookupId);
            else candidates.push(candidate);
        }
        
        let ref = new ScopeAliasItem(
            rootId,
            candidates
        );
        scope.set(ref);
    }
}