UNPKG

@logdna/setup-chain

Version:

Base class for implementing seed and resource data for test suites

140 lines (117 loc) 2.76 kB
'use strict' const {string, array, object} = require('@logdna/stdlib') const Parser = require('./parser.js') const Visitor = (new Parser).getBaseCstVisitorConstructor() const TYPES = new Map([ ['identifier', 'literal'] , ['string', 'literal'] ]) class LookupVisitor extends Visitor { constructor() { super() this.validateVisitor() } last(ctx) { return root(this.dispatch(ctx)) } dispatch(ctx) { const node = ctx.fn || ctx.lookup return this.visit(node) } lookup(ctx) { const identifiers = ctx.identifier const self = ctx.this && ctx.this[0] const node = { type: 'lookup' , data: { context: null , local: false } , value: ctx.identifier.map((node) => { return node.image }).join('.') , position: position(ctx.hash[0], identifiers[identifiers.length - 1]) } return this.wrapThis(self, node) } arg(ctx) { const value = getArg(ctx) if (value) return this.scalar(value) return this.dispatch(ctx) } wrapThis(self, child) { if (!self) return child object.set(child, 'data.local', true) return { type: 'ref' , value: self.image , position: position(self) , children: array.toArray(child) } } wrapLiteral(value) { return { type: 'literal' , value } } scalar(node) { const name = node.tokenType.name const value = name === 'string' ? node.image.replace(/^["']|['"]$/g, '') : node.image const type = TYPES.get(name) return { type: type , value: string.typecast(value) , position: position(node) } } // unwrap function args shortarguments(ctx) { return this.visit(ctx.arguments) } // unwrap function args callarguments(ctx) { return this.visit(ctx.arguments) } arguments(ctx) { const visit = this.visit.bind(this) return array.toArray(ctx.arg).map(visit) } fn(ctx) { const args = (ctx.callarguments || ctx.shortarguments) return { type: 'function' , value: ctx.identifier[0].image , position: position(ctx.bang[0], ctx.identifier[0]) , children: array.toArray(this.visit(args)) } } } module.exports = LookupVisitor function getArg(ctx) { if (ctx.string) return ctx.string[0] if (ctx.identifier) return ctx.identifier[0] } function position(start, end) { const term = end || start return { start: { offset: start.startOffset , line: start.startLine , column: start.startColumn } , end: { offset: term.startOffset + term.image.length , line: start.startLine , column: term.startColumn + term.image.length } } } function root(node) { return { type: 'root' , children: array.toArray(node) } }