From d784af00186b5a3fa50e10fc4db91ca062ea25b6 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Wed, 18 Apr 2018 14:37:27 -0700 Subject: [PATCH] WIP updated walker to return expression source --- ui/src/ifql/ast/walker.ts | 49 ++++++++++++++----- ui/src/ifql/containers/IFQLPage.tsx | 7 +-- ui/test/ifql/ast/walker.test.ts | 75 ++++++++++++++++------------- 3 files changed, 83 insertions(+), 48 deletions(-) diff --git a/ui/src/ifql/ast/walker.ts b/ui/src/ifql/ast/walker.ts index 959402c5e7..678dd6a7ab 100644 --- a/ui/src/ifql/ast/walker.ts +++ b/ui/src/ifql/ast/walker.ts @@ -2,11 +2,35 @@ import _ from 'lodash' interface Expression { - expression: object + argument: object + call: object + location: object + type: string +} + +interface Location { + source: string +} + +interface Body { + expression: Expression + location: Location + type: string +} + +interface FlatExpression { + source: string + funcs: FuncNode[] +} + +interface FuncNode { + name: string + arguments: any[] + source: string } interface AST { - body: Expression[] + body: Body[] } export default class Walker { @@ -20,9 +44,16 @@ export default class Walker { return this.buildFuncNodes(this.walk(this.baseExpression)) } - public get expressions() { - return this.baseExpressions.map(expression => { - return this.buildFuncNodes(this.walk(expression)) + public get expressions(): FlatExpression[] { + const body = _.get(this.ast, 'body', []) as Body[] + return body.map(b => { + const {location, expression} = b + const funcs = this.buildFuncNodes(this.walk(expression)) + + return { + source: location.source, + funcs, + } }) } @@ -56,7 +87,7 @@ export default class Walker { return [{name, args, source}] } - private buildFuncNodes = nodes => { + private buildFuncNodes = (nodes): FuncNode[] => { return nodes.map(({name, args, source}) => { return { name, @@ -77,11 +108,7 @@ export default class Walker { })) } - private get baseExpressions() { - return this.ast.body.map(({expression}) => expression) - } - - private get baseExpression(): Expression { + private get baseExpression() { return _.get(this.ast, 'body.0.expression', {}) } } diff --git a/ui/src/ifql/containers/IFQLPage.tsx b/ui/src/ifql/containers/IFQLPage.tsx index 07f33b53e9..82154d9ea6 100644 --- a/ui/src/ifql/containers/IFQLPage.tsx +++ b/ui/src/ifql/containers/IFQLPage.tsx @@ -193,19 +193,20 @@ export class IFQLPage extends PureComponent { const walker = new Walker(ast) const expressions = walker.expressions.map(expression => { - const funcs = this.functions(expression, suggestions) + const funcs = this.functions(expression.funcs, suggestions) return { id: uuid.v4(), funcs, + source: expression.source, } }) return expressions } - private functions = (expression, suggestions): Func[] => { - const functions = expression.map(func => { + private functions = (funcs, suggestions): Func[] => { + const functions = funcs.map(func => { const {params, name} = suggestions.find(f => f.name === func.name) const args = Object.entries(params).map(([key, type]) => { diff --git a/ui/test/ifql/ast/walker.test.ts b/ui/test/ifql/ast/walker.test.ts index 676e9b43cd..cab26f1c33 100644 --- a/ui/test/ifql/ast/walker.test.ts +++ b/ui/test/ifql/ast/walker.test.ts @@ -8,18 +8,21 @@ describe('IFQL.AST.Walker', () => { it('returns a flattened ordered list of from and its arguments', () => { const walker = new Walker(From) expect(walker.expressions).toEqual([ - [ - { - name: 'from', - source: 'from(db: "telegraf")', - arguments: [ - { - key: 'db', - value: 'telegraf', - }, - ], - }, - ], + { + source: 'from(db: "telegraf")', + funcs: [ + { + name: 'from', + source: 'from(db: "telegraf")', + arguments: [ + { + key: 'db', + value: 'telegraf', + }, + ], + }, + ], + }, ]) }) }) @@ -28,28 +31,32 @@ describe('IFQL.AST.Walker', () => { it('returns a flattened ordered list of all funcs and their arguments', () => { const walker = new Walker(Complex) expect(walker.expressions).toEqual([ - [ - { - name: 'from', - source: 'from(db: "telegraf")', - arguments: [{key: 'db', value: 'telegraf'}], - }, - { - name: 'filter', - source: '|> filter(fn: (r) => r["_measurement"] == "cpu")', - arguments: [ - { - key: 'fn', - value: '(r) => r["_measurement"] == "cpu"', - }, - ], - }, - { - name: 'range', - source: '|> range(start: -1m)', - arguments: [{key: 'start', value: '-1m'}], - }, - ], + { + source: + 'from(db: "telegraf") |> filter(fn: (r) => r["_measurement"] == "cpu") |> range(start: -1m)', + funcs: [ + { + name: 'from', + source: 'from(db: "telegraf")', + arguments: [{key: 'db', value: 'telegraf'}], + }, + { + name: 'filter', + source: '|> filter(fn: (r) => r["_measurement"] == "cpu")', + arguments: [ + { + key: 'fn', + value: '(r) => r["_measurement"] == "cpu"', + }, + ], + }, + { + name: 'range', + source: '|> range(start: -1m)', + arguments: [{key: 'start', value: '-1m'}], + }, + ], + }, ]) }) })