diff --git a/ui/src/ifql/ast/walker.ts b/ui/src/ifql/ast/walker.ts index 0b7a67afaf..1ae9dc5983 100644 --- a/ui/src/ifql/ast/walker.ts +++ b/ui/src/ifql/ast/walker.ts @@ -48,21 +48,29 @@ export default class Walker { const body = _.get(this.ast, 'body', new Array()) 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 { diff --git a/ui/test/ifql/ast/variable.ts b/ui/test/ifql/ast/variable.ts index 9c2cb0e26c..20c9951a44 100644 --- a/ui/test/ifql/ast/variable.ts +++ b/ui/test/ifql/ast/variable.ts @@ -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', + }, + }, + ], + }, + ], + }, + }, + ], + }, + ], +} diff --git a/ui/test/ifql/ast/walker.test.ts b/ui/test/ifql/ast/walker.test.ts index 7eac21d93c..87d6f45d06 100644 --- a/ui/test/ifql/ast/walker.test.ts +++ b/ui/test/ifql/ast/walker.test.ts @@ -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', + }, + ], + }, + ], + }, + ], + }, + ]) + }) }) }) })