Add ability to handle literal and expression variables

pull/10616/head
Andrew Watkins 2018-04-19 17:09:47 -07:00
parent 3acedd9a5e
commit 292d04e5a8
3 changed files with 153 additions and 24 deletions

View File

@ -48,21 +48,29 @@ export default class Walker {
const body = _.get(this.ast, 'body', new Array<Body>())
return body.map(b => {
if (b.type.includes('Expression')) {
return this.expression(b)
return this.expression(b.expression, b.location)
} else if (b.type.includes('Variable')) {
return this.variable(b)
}
})
}
private variable({type, location, declarations}) {
const dec = declarations.map(({init, id}) => {
return {name: id.name, type: init.type, value: init.value}
private variable(variable) {
const {location} = variable
const declarations = variable.declarations.map(({init, id}) => {
const {type} = init
if (type.includes('Expression')) {
const {source, funcs} = this.expression(init, location)
return {name: id.name, type, source, funcs}
}
return {name: id.name, type, value: init.value}
})
return {source: location.source, declarations: dec, type}
return {source: location.source, declarations, type: variable.type}
}
private expression({location, expression}): FlatExpression {
private expression(expression, location): FlatExpression {
const funcs = this.buildFuncNodes(this.walk(expression))
return {

View File

@ -1,4 +1,4 @@
export default {
export const StringLiteral = {
type: 'Program',
location: {
start: {line: 1, column: 1},
@ -39,3 +39,91 @@ export default {
},
],
}
export const Expression = {
type: 'Program',
location: {
start: {line: 1, column: 1},
end: {line: 1, column: 28},
source: 'tele = from(db: "telegraf")',
},
body: [
{
type: 'VariableDeclaration',
location: {
start: {line: 1, column: 1},
end: {line: 1, column: 28},
source: 'tele = from(db: "telegraf")',
},
declarations: [
{
type: 'VariableDeclarator',
id: {
type: 'Identifier',
location: {
start: {line: 1, column: 1},
end: {line: 1, column: 5},
source: 'tele',
},
name: 'tele',
},
init: {
type: 'CallExpression',
location: {
start: {line: 1, column: 8},
end: {line: 1, column: 28},
source: 'from(db: "telegraf")',
},
callee: {
type: 'Identifier',
location: {
start: {line: 1, column: 8},
end: {line: 1, column: 12},
source: 'from',
},
name: 'from',
},
arguments: [
{
type: 'ObjectExpression',
location: {
start: {line: 1, column: 13},
end: {line: 1, column: 27},
source: 'db: "telegraf"',
},
properties: [
{
type: 'Property',
location: {
start: {line: 1, column: 13},
end: {line: 1, column: 27},
source: 'db: "telegraf"',
},
key: {
type: 'Identifier',
location: {
start: {line: 1, column: 13},
end: {line: 1, column: 15},
source: 'db',
},
name: 'db',
},
value: {
type: 'StringLiteral',
location: {
start: {line: 1, column: 17},
end: {line: 1, column: 27},
source: '"telegraf"',
},
value: 'telegraf',
},
},
],
},
],
},
},
],
},
],
}

View File

@ -1,7 +1,7 @@
import Walker from 'src/ifql/ast/walker'
import From from 'test/ifql/ast/from'
import Complex from 'test/ifql/ast/complex'
import Variable from 'test/ifql/ast/variable'
import {StringLiteral, Expression} from 'test/ifql/ast/variable'
describe('IFQL.AST.Walker', () => {
describe('Walker#functions', () => {
@ -28,22 +28,55 @@ describe('IFQL.AST.Walker', () => {
])
})
describe('a single variable declaration', () => {
it('returns a variable declaration for a string literal', () => {
const walker = new Walker(Variable)
expect(walker.stuff).toEqual([
{
type: 'VariableDeclaration',
source: 'bux = "im a var"',
declarations: [
{
name: 'bux',
type: 'StringLiteral',
value: 'im a var',
},
],
},
])
describe('variables', () => {
describe('a single string literal variable', () => {
it('returns the expected list', () => {
const walker = new Walker(StringLiteral)
expect(walker.stuff).toEqual([
{
type: 'VariableDeclaration',
source: 'bux = "im a var"',
declarations: [
{
name: 'bux',
type: 'StringLiteral',
value: 'im a var',
},
],
},
])
})
})
describe('a single expression variable', () => {
it('returns the expected list', () => {
const walker = new Walker(Expression)
expect(walker.stuff).toEqual([
{
type: 'VariableDeclaration',
source: 'tele = from(db: "telegraf")',
declarations: [
{
name: 'tele',
type: 'CallExpression',
source: 'tele = from(db: "telegraf")',
funcs: [
{
name: 'from',
source: 'from(db: "telegraf")',
arguments: [
{
key: 'db',
value: 'telegraf',
},
],
},
],
},
],
},
])
})
})
})
})