From f01f7b948d338f9bab6c8f0b00a20d0a537c8d7c Mon Sep 17 00:00:00 2001 From: Christopher Henn Date: Tue, 30 Jul 2019 15:16:16 -0700 Subject: [PATCH] refactor(ui): use locally generated AST fetching utils Moves the handwritten AST wrapper types from influxdb-client-js back into the UI. Long term I think we should improve the `swagger.yml` spec for these types so that we can use their generated counterparts. This will take some tedious labor and a review from the Flux team. Part of #14482 --- ui/src/shared/apis/ast.ts | 30 -- ui/src/shared/utils/insertPreambleInScript.ts | 15 +- ui/src/types/ast.ts | 338 +++++++++++++++++- 3 files changed, 346 insertions(+), 37 deletions(-) delete mode 100644 ui/src/shared/apis/ast.ts diff --git a/ui/src/shared/apis/ast.ts b/ui/src/shared/apis/ast.ts deleted file mode 100644 index 03db74ebbf3..00000000000 --- a/ui/src/shared/apis/ast.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Libraries -import {get} from 'lodash' - -// APIs -import {client} from 'src/utils/api' - -// Types -import {Package} from 'src/types/ast' - -export const getAST = async (query: string): Promise => { - try { - const resp = await client.queries.ast(query) - - // TODO: update client Package and remove map - return { - type: 'Package', - path: resp.path, - files: resp.files, - package: resp._package || '', - } - } catch (e) { - const message = get(e, 'response.data.error') - - if (message) { - throw new Error(message) - } else { - throw e - } - } -} diff --git a/ui/src/shared/utils/insertPreambleInScript.ts b/ui/src/shared/utils/insertPreambleInScript.ts index 3a8e983b6a3..81d3c66c579 100644 --- a/ui/src/shared/utils/insertPreambleInScript.ts +++ b/ui/src/shared/utils/insertPreambleInScript.ts @@ -2,10 +2,10 @@ import {get} from 'lodash' // APIs -import {getAST} from 'src/shared/apis/ast' +import {postQueryAst} from 'src/client' // Types -import {ImportDeclaration, Statement} from 'src/types/ast' +import {Package, ImportDeclaration, Statement} from 'src/types/ast' export const insertPreambleInScript = async ( script: string, @@ -15,10 +15,13 @@ export const insertPreambleInScript = async ( return `${preamble}\n\n${script}` } - // TODO: replace this with `import {parse} from '@influxdata/flux-parser'` - // when the flux team adds location.source data to the rust implementation - // https://github.com/influxdata/influxdb/issues/14467 - const ast = await getAST(script) + const resp = await postQueryAst({data: {query: script}}) + + if (resp.status !== 200) { + throw new Error(resp.data.message) + } + + const ast = resp.data.ast as Package const imports: ImportDeclaration[] = get(ast, 'files.0.imports', []) const body: Statement[] = get(ast, 'files.0.body', []) diff --git a/ui/src/types/ast.ts b/ui/src/types/ast.ts index c358f3371df..75ce5a47421 100644 --- a/ui/src/types/ast.ts +++ b/ui/src/types/ast.ts @@ -1 +1,337 @@ -export * from '@influxdata/influx/src/types/ast' +export type Node = + | Package + | File + | PackageClause + | ImportDeclaration + | Block + | BadStatement + | ExpressionStatement + | ReturnStatement + | OptionStatement + | BuiltinStatement + | VariableAssignment + | MemberAssignment + | ArrayExpression + | FunctionExpression + | BinaryExpression + | CallExpression + | ConditionalExpression + | LogicalExpression + | MemberExpression + | IndexExpression + | PipeExpression + | ObjectExpression + | UnaryExpression + | Property + | Identifier + | BooleanLiteral + | DateTimeLiteral + | DurationLiteral + | FloatLiteral + | IntegerLiteral + | PipeLiteral + | RegexpLiteral + | StringLiteral + | UnsignedIntegerLiteral + +export interface Position { + line: number + column: number +} + +export interface SourceLocation { + file: string + start: Position + end: Position + source: string +} + +export interface BaseNode { + location?: SourceLocation + errors?: Array<{msg: string}> +} + +export interface Package extends BaseNode { + path?: string + package: string + files: File[] + type: 'Package' +} + +export interface File extends BaseNode { + name?: string + package: PackageClause + imports: ImportDeclaration[] + body: Statement[] + type: 'File' +} + +export interface PackageClause extends BaseNode { + name: Identifier + type: 'PackageClause' +} + +export interface ImportDeclaration extends BaseNode { + as: Identifier + path: StringLiteral + type: 'ImportDeclaration' +} + +export interface Block extends BaseNode { + body: Statement[] + type: 'Block' +} + +export type Statement = + | BadStatement + | ExpressionStatement + | ReturnStatement + | OptionStatement + | BuiltinStatement + | VariableAssignment + | MemberAssignment + +export interface BadStatement extends BaseNode { + text: string + type: 'BadStatement' +} + +export interface ExpressionStatement extends BaseNode { + expression: Expression + type: 'ExpressionStatement' +} + +export interface ReturnStatement extends BaseNode { + argument: Expression + type: 'ReturnStatement' +} + +export interface OptionStatement extends BaseNode { + assignment: Assignment + type: 'OptionStatement' +} + +export interface BuiltinStatement extends BaseNode { + id: Identifier + type: 'BuiltinStatement' +} + +export type Assignment = VariableAssignment | MemberAssignment + +export interface VariableAssignment extends BaseNode { + id: Identifier + init: Expression + type: 'VariableAssignment' +} + +export interface MemberAssignment extends BaseNode { + member: MemberExpression + init: Expression + type: 'MemberExpression' +} + +export type Expression = + | ArrayExpression + | FunctionExpression + | BinaryExpression + | BooleanLiteral + | CallExpression + | ConditionalExpression + | DateTimeLiteral + | DurationLiteral + | FloatLiteral + | Identifier + | IntegerLiteral + | LogicalExpression + | MemberExpression + | IndexExpression + | ObjectExpression + | PipeExpression + | PipeLiteral + | RegexpLiteral + | StringLiteral + | UnaryExpression + | UnsignedIntegerLiteral + +export interface ArrayExpression extends BaseNode { + elements: Expression[] + type: 'ArrayExpression' +} + +export interface FunctionExpression extends BaseNode { + params: Property[] + body: Node + type: 'FunctionExpression' +} + +export interface BinaryExpression extends BaseNode { + operator: Operator + left: Expression + right: Expression + type: 'BinaryExpression' +} + +export interface CallExpression extends BaseNode { + callee: Expression + arguments?: Expression[] + type: 'CallExpression' +} + +export interface ConditionalExpression extends BaseNode { + test: Expression + alternate: Expression + consequent: Expression + type: 'ConditionalExpression' +} + +export interface LogicalExpression extends BaseNode { + operator: LogicalOperator + left: Expression + right: Expression + type: 'LogicalExpression' +} + +export interface MemberExpression extends BaseNode { + object: Expression + property: PropertyKey + type: 'MemberExpression' +} + +export interface IndexExpression extends BaseNode { + array: Expression + index: Expression + type: 'IndexExpression' +} + +export interface PipeExpression extends BaseNode { + argument: Expression + call: CallExpression + type: 'PipeExpression' +} + +export interface ObjectExpression extends BaseNode { + properties: Property[] + type: 'ObjectExpression' +} + +export interface UnaryExpression extends BaseNode { + operator: Operator + argument: Expression + type: 'UnaryExpression' +} + +export interface Property extends BaseNode { + key: PropertyKey + value: Expression + type: 'Property' +} + +export interface Identifier extends BaseNode { + name: string + type: 'Identifier' +} + +export interface BooleanLiteral extends BaseNode { + value: boolean + type: 'BooleanLiteral' +} + +export interface DateTimeLiteral extends BaseNode { + value: string // RCF3339 datetime + type: 'DateTimeLiteral' +} + +export type DurationUnit = + | 'y' + | 'mo' + | 'w' + | 'd' + | 'h' + | 'm' + | 's' + | 'ms' + | 'us' + | 'µs' + | 'ns' + +export interface Duration { + magnitude: number + unit: DurationUnit +} + +export interface DurationLiteral extends BaseNode { + values: Duration[] + type: 'DurationLiteral' +} + +export interface FloatLiteral extends BaseNode { + value: number + type: 'FloatLiteral' +} + +export interface IntegerLiteral extends BaseNode { + value: number + type: 'IntegerLiteral' +} + +export interface PipeLiteral extends BaseNode { + type: 'PipeLiteral' +} + +export interface RegexpLiteral extends BaseNode { + value: string + type: 'RegexpLiteral' +} + +export interface StringLiteral extends BaseNode { + value: string + type: 'StringLiteral' +} + +export interface UnsignedIntegerLiteral extends BaseNode { + value: number + type: 'UnsignedIntegerLiteral' +} + +export type MultiplicationOperator = '*' +export type DivisionOperator = '/' +export type AdditionOperator = '+' +export type SubtractionOperator = '-' +export type LessThanEqualOperator = '<=' +export type LessThanOperator = '<' +export type GreaterThanOperator = '>' +export type GreaterThanEqualOperator = '>=' +export type InOperator = 'in' +export type NotOperator = 'not' +export type NotEmptyOperator = 'not empty' +export type EmptyOperator = 'empty' +export type StartsWithOperator = 'startswith' +export type EqualOperator = '==' +export type NotEqualOperator = '!=' +export type RegexpMatchOperator = '=~' +export type NotRegexpMatchOperator = '!~' +export type AndOperator = 'and' +export type OrOperator = 'or' + +export type Operator = + | MultiplicationOperator + | DivisionOperator + | AdditionOperator + | SubtractionOperator + | LessThanEqualOperator + | LessThanOperator + | GreaterThanOperator + | GreaterThanEqualOperator + | InOperator + | NotOperator + | NotEmptyOperator + | EmptyOperator + | StartsWithOperator + | EqualOperator + | NotEqualOperator + | RegexpMatchOperator + | NotRegexpMatchOperator + +export type LogicalOperator = AndOperator | OrOperator + +export type PropertyKey = Identifier | StringLiteral