From 023665afa8b379365649d262376c3259ce7a7ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josejulio=20Mart=C3=ADnez?= Date: Fri, 17 Apr 2020 10:44:49 -0500 Subject: [PATCH] POL-114 First version of typeahead (#87) Currently only showing the facts keys on the typeahead --- .eslintignore | 1 + package.json | 4 +- src/components/Condition/ConditionField.tsx | 106 ++ .../Condition/ConditionFieldWithFormik.tsx | 37 + src/components/Condition/ConditionVisitor.ts | 115 ++ .../__tests__/ConditionVisitor.test.ts | 65 + src/components/ConditionEditor/AndBlock.tsx | 28 - src/components/ConditionEditor/Condition.tsx | 46 - .../ConditionEditor/ConditionBlock.tsx | 33 - .../ConditionEditor/ConditionSeparator.tsx | 27 - src/components/ConditionEditor/OrBlock.tsx | 28 - src/components/Policy/PolicyWizard.tsx | 7 +- src/components/Policy/PolicyWizardTypes.ts | 2 + .../Policy/WizardSteps/ConditionsStep.tsx | 6 +- src/hooks/useFacts.ts | 16 + src/pages/ListPage/CreatePolicyWizard.tsx | 3 + src/pages/ListPage/ListPage.tsx | 3 + src/services/Api.ts | 5 +- src/services/useGetFacts.ts | 10 + src/types/Fact.ts | 9 +- src/utils/ConditionBuilder.ts | 4 + src/utils/Expression/Expression.g4 | 139 ++ src/utils/Expression/ExpressionLexer.ts | 232 ++++ src/utils/Expression/ExpressionListener.ts | 169 +++ src/utils/Expression/ExpressionParser.ts | 1189 +++++++++++++++++ src/utils/Expression/ExpressionVisitor.ts | 120 ++ tsconfig.json | 5 +- yarn.lock | 28 +- 28 files changed, 2253 insertions(+), 184 deletions(-) create mode 100644 src/components/Condition/ConditionField.tsx create mode 100644 src/components/Condition/ConditionFieldWithFormik.tsx create mode 100644 src/components/Condition/ConditionVisitor.ts create mode 100644 src/components/Condition/__tests__/ConditionVisitor.test.ts delete mode 100644 src/components/ConditionEditor/AndBlock.tsx delete mode 100644 src/components/ConditionEditor/Condition.tsx delete mode 100644 src/components/ConditionEditor/ConditionBlock.tsx delete mode 100644 src/components/ConditionEditor/ConditionSeparator.tsx delete mode 100644 src/components/ConditionEditor/OrBlock.tsx create mode 100644 src/hooks/useFacts.ts create mode 100644 src/services/useGetFacts.ts create mode 100644 src/utils/ConditionBuilder.ts create mode 100644 src/utils/Expression/Expression.g4 create mode 100644 src/utils/Expression/ExpressionLexer.ts create mode 100644 src/utils/Expression/ExpressionListener.ts create mode 100644 src/utils/Expression/ExpressionParser.ts create mode 100644 src/utils/Expression/ExpressionVisitor.ts diff --git a/.eslintignore b/.eslintignore index 3b4bc383..3edefe07 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ src/demoData/* /**/*.d.ts +src/utils/Expression/* diff --git a/package.json b/package.json index 18e64231..b314d7f0 100644 --- a/package.json +++ b/package.json @@ -12,11 +12,12 @@ "@redhat-cloud-services/frontend-components-notifications": "1.0.2", "@redhat-cloud-services/frontend-components-utilities": "1.0.0", "@redhat-cloud-services/rbac-client": "^1.0.51", + "antlr4ts": "^0.5.0-alpha.3", "axios": "^0.19.0", "classnames": "^2.2.6", "csstips": "^1.2.0", "date-fns": "^2.9.0", - "formik": "^2.0.6", + "formik": "2.1.4", "http-status-codes": "^1.4.0", "react": "^16.11.0", "react-content-loader": "^3.4.2", @@ -53,6 +54,7 @@ "@types/yup": "^0.26.26", "@typescript-eslint/eslint-plugin": "^2.9.0", "@typescript-eslint/parser": "^2.9.0", + "antlr4ts-cli": "^0.5.0-alpha.3", "babel-core": "^7.0.0-bridge.0", "babel-eslint": "^10.0.3", "babel-jest": "^24.9.0", diff --git a/src/components/Condition/ConditionField.tsx b/src/components/Condition/ConditionField.tsx new file mode 100644 index 00000000..0faea926 --- /dev/null +++ b/src/components/Condition/ConditionField.tsx @@ -0,0 +1,106 @@ +import * as React from 'react'; +import { ChangeEvent } from 'react'; +import { Select, SelectOption, SelectVariant } from '@patternfly/react-core'; +import { Fact } from '../../types/Fact'; +import { CharStreams, CommonTokenStream } from 'antlr4ts'; +import { ExpressionLexer } from '../../utils/Expression/ExpressionLexer'; +import { ExpressionParser } from '../../utils/Expression/ExpressionParser'; +import { ConditionVisitor, SuggestionType } from './ConditionVisitor'; +import { style } from 'typestyle'; + +const selectOptionClassName = style({ + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + direction: 'rtl' +}); + +const factToOptions = (base: string, facts: Fact[]): JSX.Element[] => { + return facts.map(o => ( + { base } { o.name } + )); +}; + +export interface ConditionFieldProps { + label: string; + id: string; + name: string; + facts: Fact[]; + selected: string; + onSelect: (selected: string) => void; +} + +export const ConditionField: React.FunctionComponent = (props) => { + + const { facts, onSelect, selected } = props; + const [ isOpen, setOpen ] = React.useState(false); + const [ options, setOptions ] = React.useState( + factToOptions('', facts.slice(0, 10)) + ); + + const onFilter = React.useCallback((event: ChangeEvent) => { + const localSelection = event.target.value; + onSelect(localSelection); + + const inputStream = CharStreams.fromString(localSelection); + const lexer = new ExpressionLexer(inputStream); + const tokenStream = new CommonTokenStream(lexer); + const parser = new ExpressionParser(tokenStream); + const tree = parser.expression(); + + const visitor = new ConditionVisitor(); + const result = visitor.visit(tree); + + if (result && result.suggestion.type === SuggestionType.FACT) { + const resultValue = result.value; + if (resultValue) { + setOpen(true); + const updatedSelection = localSelection.slice(0, localSelection.lastIndexOf(resultValue)).trim() + ' '; + setOptions(factToOptions(updatedSelection, facts.filter(f => f.name && f.name.includes(resultValue)).slice(0, 10))); + } else { + setOptions(factToOptions(localSelection.trim() + ' ', facts.slice(0, 10))); + } + + setOpen(true); + } else { + setOptions([]); + setOpen(false); + } + + return []; + }, [ facts, onSelect ]); + + const onSelectCallback = React.useCallback((event, selected) => { + onSelect(selected.toString()); + setOpen(false); + }, [ setOpen, onSelect ]); + + const onClear = React.useCallback(() => { + onSelect(''); + }, [ onSelect ]); + + return ( + + ); +}; diff --git a/src/components/Condition/ConditionFieldWithFormik.tsx b/src/components/Condition/ConditionFieldWithFormik.tsx new file mode 100644 index 00000000..379ad6f3 --- /dev/null +++ b/src/components/Condition/ConditionFieldWithFormik.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; +import { ConditionField, ConditionFieldProps } from './ConditionField'; +import { useField } from 'formik'; +import { FormGroup, Text, TextVariants } from '@patternfly/react-core'; + +type ConditionFieldWithFormikProp = Omit & { + isRequired?: boolean; + hint?: string; +}; + +export const ConditionFieldWithForkmik: React.FunctionComponent = (props) => { + const { hint, ...otherProps } = props; + const [ field, meta, { setValue }] = useField({ ...otherProps }); + const isValid = !meta.error || !meta.touched; + + const onSelect = React.useCallback((selected) => { + setValue(selected); + }, [ setValue ]); + + return ( + + + { hint && { hint } } + + ); +}; diff --git a/src/components/Condition/ConditionVisitor.ts b/src/components/Condition/ConditionVisitor.ts new file mode 100644 index 00000000..6a42903d --- /dev/null +++ b/src/components/Condition/ConditionVisitor.ts @@ -0,0 +1,115 @@ +import { AbstractParseTreeVisitor, ErrorNode, TerminalNode } from 'antlr4ts/tree'; + +import { ExpressionVisitor } from '../../utils/Expression/ExpressionVisitor'; +import { + ArrayContext, ExprContext, + // eslint-disable-next-line @typescript-eslint/camelcase + KeyContext, Logical_operatorContext, + ValueContext +} from '../../utils/Expression/ExpressionParser'; + +export enum SuggestionType { + FACT = 'FACT', + VALUE = 'VALUE', + LOGICAL_OPERATOR = 'LOGICAL_OPERATOR', + BOOLEAN_OPERATOR = 'BOOLEAN_OPERATOR', + ARRAY_OPERATOR = 'ARRAY_OPERATOR', + NONE = 'NO_SUGGESTION' +} + +interface SuggestionFact { + type: SuggestionType.FACT; +} + +interface SuggestionValue { + type: SuggestionType.VALUE; + fact: string; +} + +interface SuggestionLogicalOperator { + type: SuggestionType.LOGICAL_OPERATOR; +} + +interface SuggestionNone { + type: SuggestionType.NONE; +} + +type Suggestion = SuggestionFact | SuggestionValue | SuggestionLogicalOperator | SuggestionNone; + +const makeSuggestionFact = (): SuggestionFact => ({ type: SuggestionType.FACT }); +const makeSuggestionValue = (fact: string): SuggestionValue => ({ type: SuggestionType.VALUE, fact }); +const makeSuggestionLogicalOperator = (): SuggestionLogicalOperator => ({ type: SuggestionType.LOGICAL_OPERATOR }); +const makeSuggestionNone = (): SuggestionNone => ({ type: SuggestionType.NONE }); + +export class ConditionVisitorResult { + readonly suggestion: Suggestion; + readonly value: string | undefined; + + constructor(suggestion: Suggestion, value?: string) { + this.suggestion = suggestion; + this.value = value; + } + +} + +type ReturnValue = ConditionVisitorResult | undefined; + +/** + * Condition visitors returns a list of suggestions based on where we currently are. + */ +export class ConditionVisitor extends AbstractParseTreeVisitor implements ExpressionVisitor { + + protected defaultResult() { + return new ConditionVisitorResult(makeSuggestionFact()); + } + + protected aggregateResult(aggregate, nextResult) { + if (nextResult) { + return nextResult; + } + + return aggregate; + } + + visitTerminal(_node: TerminalNode) { + return undefined; + } + + visitErrorNode(_node: ErrorNode): ReturnValue { + return undefined; + } + + // eslint-disable-next-line @typescript-eslint/camelcase + visitLogical_operator(ctx: Logical_operatorContext) { + // eslint-disable-next-line new-cap + const operator = ctx.AND() || ctx.OR(); + if (!operator) { + new ConditionVisitorResult(makeSuggestionLogicalOperator()); + } + + return new ConditionVisitorResult(makeSuggestionFact()); + } + + visitKey(ctx: KeyContext) { + // eslint-disable-next-line new-cap + return new ConditionVisitorResult(makeSuggestionFact(), ctx.SIMPLETEXT().text); + } + + visitValue(ctx: ValueContext) { + // eslint-disable-next-line new-cap + const nodeValue = ctx.NUMBER() || ctx.STRING(); + + if (!nodeValue) { + if (ctx.parent instanceof ExprContext) { + // Todo: Expected value inside ExprContext + } else if (ctx.parent instanceof ArrayContext) { + // Todo: Expected value inside ArrayContext + } + + return new ConditionVisitorResult(makeSuggestionNone()); + } + + return new ConditionVisitorResult(makeSuggestionValue(''), nodeValue ? nodeValue.text : ctx.text); + } + +} diff --git a/src/components/Condition/__tests__/ConditionVisitor.test.ts b/src/components/Condition/__tests__/ConditionVisitor.test.ts new file mode 100644 index 00000000..aff09ad9 --- /dev/null +++ b/src/components/Condition/__tests__/ConditionVisitor.test.ts @@ -0,0 +1,65 @@ +import { ExpressionContext, ExpressionParser } from '../../../utils/Expression/ExpressionParser'; +import { CharStreams, CommonTokenStream } from 'antlr4ts'; +import { ExpressionLexer } from '../../../utils/Expression/ExpressionLexer'; +import { ConditionVisitor, ConditionVisitorResult, SuggestionType } from '../ConditionVisitor'; + +describe('src/components/Condition/ConditionVisitor', () => { + + const treeForCondition = (condition: string): ExpressionContext => { + const lexer = new ExpressionLexer( + CharStreams.fromString(condition) + ); + const tokenStream = new CommonTokenStream(lexer); + lexer.removeErrorListeners(); + const parser = new ExpressionParser(tokenStream); + parser.removeErrorListeners(); + return parser.expression(); + }; + + it('Provides facts on empty condition', () => { + const conditionVisitor = new ConditionVisitor(); + const result = conditionVisitor.visit(treeForCondition('')); + const expectedResult = new ConditionVisitorResult({ type: SuggestionType.FACT }); + expect(result).toEqual(expectedResult); + }); + + it('Provides facts on initial param', () => { + const conditionVisitor = new ConditionVisitor(); + const result = conditionVisitor.visit(treeForCondition('ar')); + const expectedResult = new ConditionVisitorResult({ type: SuggestionType.FACT }, 'ar'); + expect(result).toEqual(expectedResult); + }); + + it('Detects last fact on condition', () => { + const conditionVisitor = new ConditionVisitor(); + const condition = 'facts.arch = "x86_64" and cpu'; + const result = conditionVisitor.visit(treeForCondition(condition)); + const expectedResult = new ConditionVisitorResult({ type: SuggestionType.FACT }, 'cpu'); + expect(result).toEqual(expectedResult); + }); + + it('Detects when a value is being written using String', () => { + const conditionVisitor = new ConditionVisitor(); + const condition = 'facts.arch = "my-value" '; + const result = conditionVisitor.visit(treeForCondition(condition)); + const expectedResult = new ConditionVisitorResult({ type: SuggestionType.VALUE, fact: '' }, '"my-value"'); + expect(result).toEqual(expectedResult); + }); + + it('Detects when a value is being written using number', () => { + const conditionVisitor = new ConditionVisitor(); + const condition = 'facts.arch = 5'; + const result = conditionVisitor.visit(treeForCondition(condition)); + const expectedResult = new ConditionVisitorResult({ type: SuggestionType.VALUE, fact: '' }, '5'); + expect(result).toEqual(expectedResult); + }); + + it('Detects a fact is after a logical operator', () => { + const conditionVisitor = new ConditionVisitor(); + const condition = 'facts.arch = 5 and '; + const result = conditionVisitor.visit(treeForCondition(condition)); + const expectedResult = new ConditionVisitorResult({ type: SuggestionType.FACT }); + expect(result).toEqual(expectedResult); + }); + +}); diff --git a/src/components/ConditionEditor/AndBlock.tsx b/src/components/ConditionEditor/AndBlock.tsx deleted file mode 100644 index 792bd894..00000000 --- a/src/components/ConditionEditor/AndBlock.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react'; -import { style } from 'typestyle'; - -import { ConditionSeparator } from './ConditionSeparator'; -import { ConditionBlock } from './ConditionBlock'; - -const andBlockClassName = style({ - backgroundColor: '#ffffff', - padding: '15px', - width: '690px' -}); - -interface AndBlockProps { - addCondition: () => void; -} - -const AndSeparator = () => { - return ; -}; - -export const AndBlock: React.FunctionComponent = (props: React.PropsWithChildren) => { - return { props.children }; -}; diff --git a/src/components/ConditionEditor/Condition.tsx b/src/components/ConditionEditor/Condition.tsx deleted file mode 100644 index a1e7ada5..00000000 --- a/src/components/ConditionEditor/Condition.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from 'react'; -import { TextInput, FormSelect, FormSelectOption, Flex, FlexItem } from '@patternfly/react-core'; - -type KeyValue = { - [key: string]: string; -}; - -interface ConditionProps { - fact: KeyValue; // Todo: Use `fact` model. - operator: KeyValue; - value?: string | null; // This can be several things and we could tie it with the fact type. - - children?: undefined; -} - -interface SelectWithValuesProps { - 'aria-label': string; - values: KeyValue; -} - -const SelectWithValues: React.FunctionComponent = (props: SelectWithValuesProps) => { - return ( - - { Object.keys(props.values).map(key => ) } - - ); -}; - -export const Condition: React.FunctionComponent = (props: ConditionProps) => { - return ( - - - - - - - - - - - - ); -}; diff --git a/src/components/ConditionEditor/ConditionBlock.tsx b/src/components/ConditionEditor/ConditionBlock.tsx deleted file mode 100644 index e8083132..00000000 --- a/src/components/ConditionEditor/ConditionBlock.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from 'react'; -import FlexView from 'react-flexview/lib/FlexView'; -import { Button } from '@patternfly/react-core'; -import { verticallySpaced } from 'csstips'; -import { style } from 'typestyle'; - -import * as ComponentUtils from '../../utils/ComponentUtils'; - -interface ConditionBlockProps { - buttonText: string; - className: string; - onClick: () => void; - separatorType: React.ComponentType; -} - -const styleVerticallyScaped15 = style(verticallySpaced(15)); - -export const ConditionBlock: React.FunctionComponent = (props: React.PropsWithChildren) => { - const decoratedChildren = React.Children.map(props.children, (child) => { - let key: React.Key | undefined = undefined; - if (React.isValidElement(child)) { - key = child.props.key; - } - - return <>{ child } ; - }); - return ( - - {ComponentUtils.join(decoratedChildren, props.separatorType)} - - - ); -}; diff --git a/src/components/ConditionEditor/ConditionSeparator.tsx b/src/components/ConditionEditor/ConditionSeparator.tsx deleted file mode 100644 index a5f7d053..00000000 --- a/src/components/ConditionEditor/ConditionSeparator.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react'; -import FlexView from 'react-flexview/lib/FlexView'; -import { style } from 'typestyle'; - -interface ConditionSeparatorProps { - content: React.ReactNode; -} - -const separatorClass = style({ - $nest: { - '&::after': { - content: `''`, - backgroundColor: 'black', - height: 1, - position: 'relative', - width: '100%', - left: '0.5em', - marginRight: '15px' - } - } -}); - -export const ConditionSeparator: React.FunctionComponent = (props: ConditionSeparatorProps) => { - return ( - <>{ props.content } - ); -}; diff --git a/src/components/ConditionEditor/OrBlock.tsx b/src/components/ConditionEditor/OrBlock.tsx deleted file mode 100644 index 42e01347..00000000 --- a/src/components/ConditionEditor/OrBlock.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react'; -import { style } from 'typestyle'; - -import { ConditionBlock } from './ConditionBlock'; -import { ConditionSeparator } from './ConditionSeparator'; - -const orBlockClassName = style({ - backgroundColor: '#dddddd', - padding: '15px', - width: '620px' -}); - -interface OrBlockProps { - addCondition: () => void; -} - -const OrSeparator = () => { - return ; -}; - -export const OrBlock: React.FunctionComponent = (props: React.PropsWithChildren) => { - return { props.children }; -}; diff --git a/src/components/Policy/PolicyWizard.tsx b/src/components/Policy/PolicyWizard.tsx index 14ec51d2..1941caec 100644 --- a/src/components/Policy/PolicyWizard.tsx +++ b/src/components/Policy/PolicyWizard.tsx @@ -18,6 +18,7 @@ import { PolicyFormSchema } from '../../schemas/CreatePolicy/PolicySchema'; import { PolicyWizardFooter } from './PolicyWizardFooter'; import { Policy, NewPolicy } from '../../types/Policy/Policy'; import { useMountedState } from 'react-use'; +import { Fact } from '../../types/Fact'; interface PolicyWizardProps { initialValue: PartialPolicy; @@ -27,6 +28,7 @@ interface PolicyWizardProps { isLoading: boolean; showCreateStep: boolean; policiesExist?: boolean; + facts?: Fact[]; } const buildSteps: (showCreateStep: boolean) => WizardStepExtended[] = (showCreateStep) => { @@ -97,6 +99,7 @@ interface FormikBindingProps { onClose: () => void; showCreateStep: boolean; policiesExist?: boolean; + facts?: Fact[]; } const FormikBinding: React.FunctionComponent = (props) => { @@ -121,7 +124,8 @@ const FormikBinding: React.FunctionComponent = (props) => { triggerAction: props.triggerAction, verifyResponse: props.verifyResponse, createResponse: props.createResponse, - setVerifyResponse: props.setVerifyResponse + setVerifyResponse: props.setVerifyResponse, + facts: props.facts }; const isValid = isStepValid(props.steps[props.currentStep], wizardContext, formikProps.values); @@ -251,6 +255,7 @@ export const PolicyWizard: React.FunctionComponent = (props: onMove={ onMove } showCreateStep={ props.showCreateStep } policiesExist={ props.policiesExist } + facts={ props.facts } /> diff --git a/src/components/Policy/PolicyWizardTypes.ts b/src/components/Policy/PolicyWizardTypes.ts index 375089fb..cce1ebe8 100644 --- a/src/components/Policy/PolicyWizardTypes.ts +++ b/src/components/Policy/PolicyWizardTypes.ts @@ -4,6 +4,7 @@ import * as Yup from 'yup'; import { WizardStep } from '@patternfly/react-core'; import { DeepPartial, DeepReadonly } from 'ts-essentials'; import { Policy } from '../../types/Policy'; +import { Fact } from '../../types/Fact'; export type PartialPolicy = DeepPartial; @@ -39,6 +40,7 @@ export interface WizardContext { verifyResponse: VerifyPolicyResponse; createResponse: CreatePolicyResponse; setVerifyResponse: (verifyResponse: VerifyPolicyResponse) => void; + facts?: Fact[]; } export const WizardContext = React.createContext({ diff --git a/src/components/Policy/WizardSteps/ConditionsStep.tsx b/src/components/Policy/WizardSteps/ConditionsStep.tsx index 8e144488..074be989 100644 --- a/src/components/Policy/WizardSteps/ConditionsStep.tsx +++ b/src/components/Policy/WizardSteps/ConditionsStep.tsx @@ -10,7 +10,6 @@ import { } from '@patternfly/react-core'; import { ExclamationCircleIcon, CheckCircleIcon } from '@patternfly/react-icons'; -import { FormTextInput } from '../../Formik/Patternfly'; import { PartialPolicy, WizardActionType, WizardContext, WizardStepExtended } from '../PolicyWizardTypes'; import { PolicyFormConditions } from '../../../schemas/CreatePolicy/PolicySchema'; import { useFormikContext } from 'formik'; @@ -19,6 +18,7 @@ import { GlobalDangerColor100, GlobalSuccessColor200 } from '../../../utils/PFCo import { Messages } from '../../../properties/Messages'; import { joinClasses } from '../../../utils/ComponentUtils'; import { Form } from '../../Formik/Patternfly/Form'; +import { ConditionFieldWithForkmik } from '../../Condition/ConditionFieldWithFormik'; const elementClassName = style({ marginTop: 'auto', @@ -122,8 +122,8 @@ const ConditionsStep: React.FunctionComponent = () => { return (
{ Messages.wizards.policy.conditions.title } - diff --git a/src/hooks/useFacts.ts b/src/hooks/useFacts.ts new file mode 100644 index 00000000..b32072d5 --- /dev/null +++ b/src/hooks/useFacts.ts @@ -0,0 +1,16 @@ +import { useEffect, useState } from 'react'; +import { Fact } from '../types/Fact'; +import { useGetFactsQuery } from '../services/useGetFacts'; + +export const useFacts = () => { + const [ facts, setFacts ] = useState(); + const { payload: factsPayload } = useGetFactsQuery(true); + + useEffect(() => { + if (factsPayload) { + setFacts(factsPayload); + } + }, [ factsPayload, setFacts ]); + + return facts; +}; diff --git a/src/pages/ListPage/CreatePolicyWizard.tsx b/src/pages/ListPage/CreatePolicyWizard.tsx index 8add3e33..9b5f3444 100644 --- a/src/pages/ListPage/CreatePolicyWizard.tsx +++ b/src/pages/ListPage/CreatePolicyWizard.tsx @@ -6,12 +6,14 @@ import * as HttpStatus from 'http-status-codes'; import { addSuccessNotification } from '../../utils/AlertUtils'; import { CreatePolicyResponse, VerifyPolicyResponse } from '../../components/Policy/PolicyWizardTypes'; import { Policy, NewPolicy } from '../../types/Policy/Policy'; +import { Fact } from '../../types/Fact'; type CreatePolicyWizardBase = { close: (policyCreated: boolean) => void; initialValue?: NewPolicy; showCreateStep: boolean; policiesExist?: boolean; + facts?: Fact[]; }; type CreatePolicyWizardIsOpen = { @@ -84,6 +86,7 @@ export const CreatePolicyWizard: React.FunctionComponent} ); diff --git a/src/pages/ListPage/ListPage.tsx b/src/pages/ListPage/ListPage.tsx index ad2f4790..95562cb7 100644 --- a/src/pages/ListPage/ListPage.tsx +++ b/src/pages/ListPage/ListPage.tsx @@ -22,6 +22,7 @@ import { EmailOptIn } from '../../components/EmailOptIn/EmailOptIn'; import { Messages } from '../../properties/Messages'; import { useBulkChangePolicyEnabledMutation } from '../../services/useChangePolicyEnabled'; import { style } from 'typestyle'; +import { useFacts } from '../../hooks/useFacts'; type ListPageProps = {}; @@ -60,6 +61,7 @@ const ListPage: React.FunctionComponent = (_props) => { const isLoading = getPoliciesQuery.loading || bulkChangePolicyEnabledMutation.loading; const policyRows = usePolicyRows(getPoliciesQuery.payload, isLoading); + const facts = useFacts(); const { canWriteAll, canReadAll } = appContext.rbac; @@ -254,6 +256,7 @@ const ListPage: React.FunctionComponent = (_props) => { initialValue={ policyWizardState.template } showCreateStep={ policyWizardState.showCreateStep } policiesExist={ getPoliciesQuery.count > 0 ? true : false } + facts={ facts } /> } diff --git a/src/services/Api.ts b/src/services/Api.ts index fd7dbac2..d2f48f50 100644 --- a/src/services/Api.ts +++ b/src/services/Api.ts @@ -1,7 +1,6 @@ import Config from '../config/Config'; import { PagedServerPolicyResponse, Policy } from '../types/Policy/Policy'; -import { useBulkMutation, useMutation, useQuery } from 'react-fetching-library'; -import { Fact } from '../types/Fact'; +import { useMutation, useQuery, useBulkMutation } from 'react-fetching-library'; import { Page } from '../types/Page'; import { toPolicies, toServerPolicy } from '../utils/PolicyAdapter'; import { UsePaginatedQueryResponse, useTransformQueryResponse } from '../utils/ApiUtils'; @@ -12,8 +11,6 @@ import { paginatedActionBuilder } from './Api/PaginatedActionBuilder'; const urls = Config.apis.urls; -export const useGetFactsQuery = (initFetch?: boolean) => useQuery(actionBuilder('GET', urls.facts).build(), initFetch); - export const useGetPoliciesQuery = (page?: Page, initFetch?: boolean): UsePaginatedQueryResponse => { return useTransformQueryResponse( useNewPaginatedQuery(paginatedActionBuilder('GET', urls.policies).page(page).build(), initFetch), diff --git a/src/services/useGetFacts.ts b/src/services/useGetFacts.ts new file mode 100644 index 00000000..5a4aae1c --- /dev/null +++ b/src/services/useGetFacts.ts @@ -0,0 +1,10 @@ +import { Fact } from '../types/Fact'; +import Config from '../config/Config'; +import { useQuery } from 'react-fetching-library'; +import { actionBuilder } from './Api/ActionBuilder'; + +const urls = Config.apis.urls; + +export const actionCreator = () => actionBuilder('GET', urls.facts).build(); + +export const useGetFactsQuery = (initFetch?: boolean) => useQuery(actionCreator(), initFetch); diff --git a/src/types/Fact.ts b/src/types/Fact.ts index a9867a61..2205635c 100644 --- a/src/types/Fact.ts +++ b/src/types/Fact.ts @@ -1,8 +1,5 @@ +import * as Generated from './GeneratedOpenApi'; -export type FactType = 'BOOLEAN' | 'INT' | 'STRING'; +export type FactType = Generated.FactType; -export interface Fact { - id: number; - name: string; - type: FactType; -} +export type Fact = Generated.Fact; diff --git a/src/utils/ConditionBuilder.ts b/src/utils/ConditionBuilder.ts new file mode 100644 index 00000000..9916f994 --- /dev/null +++ b/src/utils/ConditionBuilder.ts @@ -0,0 +1,4 @@ + +export class ConditionBuilder { + +} diff --git a/src/utils/Expression/Expression.g4 b/src/utils/Expression/Expression.g4 new file mode 100644 index 00000000..772e4d55 --- /dev/null +++ b/src/utils/Expression/Expression.g4 @@ -0,0 +1,139 @@ +grammar Expression; + +//lexer +expression + : object EOF + ; + +object + : negative_expr object + | expr + | '(' object ')' + | object logical_operator object + ; + +expr + : key + | key boolean_operator value + | key numeric_compare_operator numerical_value + | key string_compare_operator array + | key string_compare_operator value + | key array_operator array + ; + +logical_operator + : AND + | OR + ; + +boolean_operator + : EQUAL + | NOTEQUAL + ; + +numeric_compare_operator + : GT + | GTE + | LT + | LTE + ; + +string_compare_operator + : CONTAINS + ; + +array_operator + : IN + | CONTAINS + ; + +array + : '[' value (',' value)* ']' + | '[' ']' // empty array + ; + +numerical_value + : NUMBER + ; + +value + : NUMBER + | STRING + ; + +negative_expr + : NEG + | NOT + ; + +key + : SIMPLETEXT + ; + +//parser +OR: O R; +AND: A N D; +NOT: N O T; +EQUAL: '='; +NOTEQUAL: '!='; +CONTAINS: C O N T A I N S; +NEG: NEG_OP; + +// Allow only for numbers +GT: '>'; +GTE: '>='; +LT: '<'; +LTE: '<='; + +// Allow only for array? +IN: I N; + +// Needs maybe INTEGER OR FLOAT? Use fragments? +NUMBER : INTEGER ('.' INTEGER)? ; + +FLOAT : INTEGER '.' INTEGER ; +INTEGER : [0-9]+ ; + +SIMPLETEXT : [a-zA-Z_0-9.]([\-a-zA-Z_0-9.] | ESC_DOT)* ; +STRING : '\'' ( ESC | ~('\\'|'\'') )* '\'' + |'"' ( ESC | ~('\\'|'"') )* '"'; +//COMPLEXTEXT : '\'' (ESC | ~['\\])* '\'' ; + +WS : [ \t\n\r]+ -> skip ; + + +//fragments +fragment ESC : '\\' (['\\/bfnrt] | UNICODE | NEG_OP) ; +fragment UNICODE : 'u' HEX HEX HEX HEX ; +fragment HEX : [0-9a-fA-F] ; + +fragment ESC_DOT : '\\.'; + +fragment A: [aA]; +fragment B: [bB]; +fragment C: [cC]; +fragment D: [dD]; +fragment E: [eE]; +fragment F: [fF]; +fragment G: [gG]; +fragment H: [hH]; +fragment I: [iI]; +fragment J: [jJ]; +fragment K: [kK]; +fragment L: [lL]; +fragment M: [mM]; +fragment N: [nN]; +fragment O: [oO]; +fragment P: [pP]; +fragment Q: [qQ]; +fragment R: [rR]; +fragment S: [sS]; +fragment T: [tT]; +fragment U: [uU]; +fragment V: [vV]; +fragment W: [wW]; +fragment X: [xX]; +fragment Y: [yY]; +fragment Z: [zZ]; + +fragment NEG_OP: '!'; \ No newline at end of file diff --git a/src/utils/Expression/ExpressionLexer.ts b/src/utils/Expression/ExpressionLexer.ts new file mode 100644 index 00000000..216551aa --- /dev/null +++ b/src/utils/Expression/ExpressionLexer.ts @@ -0,0 +1,232 @@ +// Generated from /home/josejulio/Documentos/redhat/insights/custom-policies-ui-frontend/utils/Expression.g4 by ANTLR 4.7.3-SNAPSHOT + + +import { ATN } from "antlr4ts/atn/ATN"; +import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer"; +import { CharStream } from "antlr4ts/CharStream"; +import { Lexer } from "antlr4ts/Lexer"; +import { LexerATNSimulator } from "antlr4ts/atn/LexerATNSimulator"; +import { NotNull } from "antlr4ts/Decorators"; +import { Override } from "antlr4ts/Decorators"; +import { RuleContext } from "antlr4ts/RuleContext"; +import { Vocabulary } from "antlr4ts/Vocabulary"; +import { VocabularyImpl } from "antlr4ts/VocabularyImpl"; + +import * as Utils from "antlr4ts/misc/Utils"; + + +export class ExpressionLexer extends Lexer { + public static readonly T__0 = 1; + public static readonly T__1 = 2; + public static readonly T__2 = 3; + public static readonly T__3 = 4; + public static readonly T__4 = 5; + public static readonly OR = 6; + public static readonly AND = 7; + public static readonly NOT = 8; + public static readonly EQUAL = 9; + public static readonly NOTEQUAL = 10; + public static readonly CONTAINS = 11; + public static readonly NEG = 12; + public static readonly GT = 13; + public static readonly GTE = 14; + public static readonly LT = 15; + public static readonly LTE = 16; + public static readonly IN = 17; + public static readonly NUMBER = 18; + public static readonly FLOAT = 19; + public static readonly INTEGER = 20; + public static readonly SIMPLETEXT = 21; + public static readonly STRING = 22; + public static readonly WS = 23; + + // tslint:disable:no-trailing-whitespace + public static readonly channelNames: string[] = [ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", + ]; + + // tslint:disable:no-trailing-whitespace + public static readonly modeNames: string[] = [ + "DEFAULT_MODE", + ]; + + public static readonly ruleNames: string[] = [ + "T__0", "T__1", "T__2", "T__3", "T__4", "OR", "AND", "NOT", "EQUAL", "NOTEQUAL", + "CONTAINS", "NEG", "GT", "GTE", "LT", "LTE", "IN", "NUMBER", "FLOAT", + "INTEGER", "SIMPLETEXT", "STRING", "WS", "ESC", "UNICODE", "HEX", "ESC_DOT", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", + "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "NEG_OP", + ]; + + private static readonly _LITERAL_NAMES: Array = [ + undefined, "'('", "')'", "'['", "','", "']'", undefined, undefined, undefined, + "'='", "'!='", undefined, undefined, "'>'", "'>='", "'<'", "'<='", + ]; + private static readonly _SYMBOLIC_NAMES: Array = [ + undefined, undefined, undefined, undefined, undefined, undefined, "OR", + "AND", "NOT", "EQUAL", "NOTEQUAL", "CONTAINS", "NEG", "GT", "GTE", "LT", + "LTE", "IN", "NUMBER", "FLOAT", "INTEGER", "SIMPLETEXT", "STRING", "WS", + ]; + public static readonly VOCABULARY: Vocabulary = new VocabularyImpl(ExpressionLexer._LITERAL_NAMES, ExpressionLexer._SYMBOLIC_NAMES, []); + + // @Override + // @NotNull + public get vocabulary(): Vocabulary { + return ExpressionLexer.VOCABULARY; + } + // tslint:enable:no-trailing-whitespace + + + constructor(input: CharStream) { + super(input); + this._interp = new LexerATNSimulator(ExpressionLexer._ATN, this); + } + + // @Override + public get grammarFileName(): string { return "Expression.g4"; } + + // @Override + public get ruleNames(): string[] { return ExpressionLexer.ruleNames; } + + // @Override + public get serializedATN(): string { return ExpressionLexer._serializedATN; } + + // @Override + public get channelNames(): string[] { return ExpressionLexer.channelNames; } + + // @Override + public get modeNames(): string[] { return ExpressionLexer.modeNames; } + + public static readonly _serializedATN: string = + "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x02\x19\u0119\b\x01" + + "\x04\x02\t\x02\x04\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04\x06\t\x06" + + "\x04\x07\t\x07\x04\b\t\b\x04\t\t\t\x04\n\t\n\x04\v\t\v\x04\f\t\f\x04\r" + + "\t\r\x04\x0E\t\x0E\x04\x0F\t\x0F\x04\x10\t\x10\x04\x11\t\x11\x04\x12\t" + + "\x12\x04\x13\t\x13\x04\x14\t\x14\x04\x15\t\x15\x04\x16\t\x16\x04\x17\t" + + "\x17\x04\x18\t\x18\x04\x19\t\x19\x04\x1A\t\x1A\x04\x1B\t\x1B\x04\x1C\t" + + "\x1C\x04\x1D\t\x1D\x04\x1E\t\x1E\x04\x1F\t\x1F\x04 \t \x04!\t!\x04\"\t" + + "\"\x04#\t#\x04$\t$\x04%\t%\x04&\t&\x04\'\t\'\x04(\t(\x04)\t)\x04*\t*\x04" + + "+\t+\x04,\t,\x04-\t-\x04.\t.\x04/\t/\x040\t0\x041\t1\x042\t2\x043\t3\x04" + + "4\t4\x045\t5\x046\t6\x047\t7\x03\x02\x03\x02\x03\x03\x03\x03\x03\x04\x03" + + "\x04\x03\x05\x03\x05\x03\x06\x03\x06\x03\x07\x03\x07\x03\x07\x03\b\x03" + + "\b\x03\b\x03\b\x03\t\x03\t\x03\t\x03\t\x03\n\x03\n\x03\v\x03\v\x03\v\x03" + + "\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\r\x03\r\x03\x0E" + + "\x03\x0E\x03\x0F\x03\x0F\x03\x0F\x03\x10\x03\x10\x03\x11\x03\x11\x03\x11" + + "\x03\x12\x03\x12\x03\x12\x03\x13\x03\x13\x03\x13\x05\x13\xA5\n\x13\x03" + + "\x14\x03\x14\x03\x14\x03\x14\x03\x15\x06\x15\xAC\n\x15\r\x15\x0E\x15\xAD" + + "\x03\x16\x03\x16\x03\x16\x07\x16\xB3\n\x16\f\x16\x0E\x16\xB6\v\x16\x03" + + "\x17\x03\x17\x03\x17\x07\x17\xBB\n\x17\f\x17\x0E\x17\xBE\v\x17\x03\x17" + + "\x03\x17\x03\x17\x03\x17\x07\x17\xC4\n\x17\f\x17\x0E\x17\xC7\v\x17\x03" + + "\x17\x05\x17\xCA\n\x17\x03\x18\x06\x18\xCD\n\x18\r\x18\x0E\x18\xCE\x03" + + "\x18\x03\x18\x03\x19\x03\x19\x03\x19\x03\x19\x05\x19\xD7\n\x19\x03\x1A" + + "\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1B\x03\x1B\x03\x1C\x03\x1C" + + "\x03\x1C\x03\x1D\x03\x1D\x03\x1E\x03\x1E\x03\x1F\x03\x1F\x03 \x03 \x03" + + "!\x03!\x03\"\x03\"\x03#\x03#\x03$\x03$\x03%\x03%\x03&\x03&\x03\'\x03\'" + + "\x03(\x03(\x03)\x03)\x03*\x03*\x03+\x03+\x03,\x03,\x03-\x03-\x03.\x03" + + ".\x03/\x03/\x030\x030\x031\x031\x032\x032\x033\x033\x034\x034\x035\x03" + + "5\x036\x036\x037\x037\x02\x02\x028\x03\x02\x03\x05\x02\x04\x07\x02\x05" + + "\t\x02\x06\v\x02\x07\r\x02\b\x0F\x02\t\x11\x02\n\x13\x02\v\x15\x02\f\x17" + + "\x02\r\x19\x02\x0E\x1B\x02\x0F\x1D\x02\x10\x1F\x02\x11!\x02\x12#\x02\x13" + + "%\x02\x14\'\x02\x15)\x02\x16+\x02\x17-\x02\x18/\x02\x191\x02\x023\x02" + + "\x025\x02\x027\x02\x029\x02\x02;\x02\x02=\x02\x02?\x02\x02A\x02\x02C\x02" + + "\x02E\x02\x02G\x02\x02I\x02\x02K\x02\x02M\x02\x02O\x02\x02Q\x02\x02S\x02" + + "\x02U\x02\x02W\x02\x02Y\x02\x02[\x02\x02]\x02\x02_\x02\x02a\x02\x02c\x02" + + "\x02e\x02\x02g\x02\x02i\x02\x02k\x02\x02m\x02\x02\x03\x02$\x03\x022;\x07" + + "\x02002;C\\aac|\x07\x02/02;C\\aac|\x04\x02))^^\x04\x02$$^^\x05\x02\v\f" + + "\x0F\x0F\"\"\n\x02))11^^ddhhppttvv\x05\x022;CHch\x04\x02CCcc\x04\x02D" + + "Ddd\x04\x02EEee\x04\x02FFff\x04\x02GGgg\x04\x02HHhh\x04\x02IIii\x04\x02" + + "JJjj\x04\x02KKkk\x04\x02LLll\x04\x02MMmm\x04\x02NNnn\x04\x02OOoo\x04\x02" + + "PPpp\x04\x02QQqq\x04\x02RRrr\x04\x02SSss\x04\x02TTtt\x04\x02UUuu\x04\x02" + + "VVvv\x04\x02WWww\x04\x02XXxx\x04\x02YYyy\x04\x02ZZzz\x04\x02[[{{\x04\x02" + + "\\\\||\x02\u0105\x02\x03\x03\x02\x02\x02\x02\x05\x03\x02\x02\x02\x02\x07" + + "\x03\x02\x02\x02\x02\t\x03\x02\x02\x02\x02\v\x03\x02\x02\x02\x02\r\x03" + + "\x02\x02\x02\x02\x0F\x03\x02\x02\x02\x02\x11\x03\x02\x02\x02\x02\x13\x03" + + "\x02\x02\x02\x02\x15\x03\x02\x02\x02\x02\x17\x03\x02\x02\x02\x02\x19\x03" + + "\x02\x02\x02\x02\x1B\x03\x02\x02\x02\x02\x1D\x03\x02\x02\x02\x02\x1F\x03" + + "\x02\x02\x02\x02!\x03\x02\x02\x02\x02#\x03\x02\x02\x02\x02%\x03\x02\x02" + + "\x02\x02\'\x03\x02\x02\x02\x02)\x03\x02\x02\x02\x02+\x03\x02\x02\x02\x02" + + "-\x03\x02\x02\x02\x02/\x03\x02\x02\x02\x03o\x03\x02\x02\x02\x05q\x03\x02" + + "\x02\x02\x07s\x03\x02\x02\x02\tu\x03\x02\x02\x02\vw\x03\x02\x02\x02\r" + + "y\x03\x02\x02\x02\x0F|\x03\x02\x02\x02\x11\x80\x03\x02\x02\x02\x13\x84" + + "\x03\x02\x02\x02\x15\x86\x03\x02\x02\x02\x17\x89\x03\x02\x02\x02\x19\x92" + + "\x03\x02\x02\x02\x1B\x94\x03\x02\x02\x02\x1D\x96\x03\x02\x02\x02\x1F\x99" + + "\x03\x02\x02\x02!\x9B\x03\x02\x02\x02#\x9E\x03\x02\x02\x02%\xA1\x03\x02" + + "\x02\x02\'\xA6\x03\x02\x02\x02)\xAB\x03\x02\x02\x02+\xAF\x03\x02\x02\x02" + + "-\xC9\x03\x02\x02\x02/\xCC\x03\x02\x02\x021\xD2\x03\x02\x02\x023\xD8\x03" + + "\x02\x02\x025\xDE\x03\x02\x02\x027\xE0\x03\x02\x02\x029\xE3\x03\x02\x02" + + "\x02;\xE5\x03\x02\x02\x02=\xE7\x03\x02\x02\x02?\xE9\x03\x02\x02\x02A\xEB" + + "\x03\x02\x02\x02C\xED\x03\x02\x02\x02E\xEF\x03\x02\x02\x02G\xF1\x03\x02" + + "\x02\x02I\xF3\x03\x02\x02\x02K\xF5\x03\x02\x02\x02M\xF7\x03\x02\x02\x02" + + "O\xF9\x03\x02\x02\x02Q\xFB\x03\x02\x02\x02S\xFD\x03\x02\x02\x02U\xFF\x03" + + "\x02\x02\x02W\u0101\x03\x02\x02\x02Y\u0103\x03\x02\x02\x02[\u0105\x03" + + "\x02\x02\x02]\u0107\x03\x02\x02\x02_\u0109\x03\x02\x02\x02a\u010B\x03" + + "\x02\x02\x02c\u010D\x03\x02\x02\x02e\u010F\x03\x02\x02\x02g\u0111\x03" + + "\x02\x02\x02i\u0113\x03\x02\x02\x02k\u0115\x03\x02\x02\x02m\u0117\x03" + + "\x02\x02\x02op\x07*\x02\x02p\x04\x03\x02\x02\x02qr\x07+\x02\x02r\x06\x03" + + "\x02\x02\x02st\x07]\x02\x02t\b\x03\x02\x02\x02uv\x07.\x02\x02v\n\x03\x02" + + "\x02\x02wx\x07_\x02\x02x\f\x03\x02\x02\x02yz\x05U+\x02z{\x05[.\x02{\x0E" + + "\x03\x02\x02\x02|}\x059\x1D\x02}~\x05S*\x02~\x7F\x05? \x02\x7F\x10\x03" + + "\x02\x02\x02\x80\x81\x05S*\x02\x81\x82\x05U+\x02\x82\x83\x05_0\x02\x83" + + "\x12\x03\x02\x02\x02\x84\x85\x07?\x02\x02\x85\x14\x03\x02\x02\x02\x86" + + "\x87\x07#\x02\x02\x87\x88\x07?\x02\x02\x88\x16\x03\x02\x02\x02\x89\x8A" + + "\x05=\x1F\x02\x8A\x8B\x05U+\x02\x8B\x8C\x05S*\x02\x8C\x8D\x05_0\x02\x8D" + + "\x8E\x059\x1D\x02\x8E\x8F\x05I%\x02\x8F\x90\x05S*\x02\x90\x91\x05]/\x02" + + "\x91\x18\x03\x02\x02\x02\x92\x93\x05m7\x02\x93\x1A\x03\x02\x02\x02\x94" + + "\x95\x07@\x02\x02\x95\x1C\x03\x02\x02\x02\x96\x97\x07@\x02\x02\x97\x98" + + "\x07?\x02\x02\x98\x1E\x03\x02\x02\x02\x99\x9A\x07>\x02\x02\x9A \x03\x02" + + "\x02\x02\x9B\x9C\x07>\x02\x02\x9C\x9D\x07?\x02\x02\x9D\"\x03\x02\x02\x02" + + "\x9E\x9F\x05I%\x02\x9F\xA0\x05S*\x02\xA0$\x03\x02\x02\x02\xA1\xA4\x05" + + ")\x15\x02\xA2\xA3\x070\x02\x02\xA3\xA5\x05)\x15\x02\xA4\xA2\x03\x02\x02" + + "\x02\xA4\xA5\x03\x02\x02\x02\xA5&\x03\x02\x02\x02\xA6\xA7\x05)\x15\x02" + + "\xA7\xA8\x070\x02\x02\xA8\xA9\x05)\x15\x02\xA9(\x03\x02\x02\x02\xAA\xAC" + + "\t\x02\x02\x02\xAB\xAA\x03\x02\x02\x02\xAC\xAD\x03\x02\x02\x02\xAD\xAB" + + "\x03\x02\x02\x02\xAD\xAE\x03\x02\x02\x02\xAE*\x03\x02\x02\x02\xAF\xB4" + + "\t\x03\x02\x02\xB0\xB3\t\x04\x02\x02\xB1\xB3\x057\x1C\x02\xB2\xB0\x03" + + "\x02\x02\x02\xB2\xB1\x03\x02\x02\x02\xB3\xB6\x03\x02\x02\x02\xB4\xB2\x03" + + "\x02\x02\x02\xB4\xB5\x03\x02\x02\x02\xB5,\x03\x02\x02\x02\xB6\xB4\x03" + + "\x02\x02\x02\xB7\xBC\x07)\x02\x02\xB8\xBB\x051\x19\x02\xB9\xBB\n\x05\x02" + + "\x02\xBA\xB8\x03\x02\x02\x02\xBA\xB9\x03\x02\x02\x02\xBB\xBE\x03\x02\x02" + + "\x02\xBC\xBA\x03\x02\x02\x02\xBC\xBD\x03\x02\x02\x02\xBD\xBF\x03\x02\x02" + + "\x02\xBE\xBC\x03\x02\x02\x02\xBF\xCA\x07)\x02\x02\xC0\xC5\x07$\x02\x02" + + "\xC1\xC4\x051\x19\x02\xC2\xC4\n\x06\x02\x02\xC3\xC1\x03\x02\x02\x02\xC3" + + "\xC2\x03\x02\x02\x02\xC4\xC7\x03\x02\x02\x02\xC5\xC3\x03\x02\x02\x02\xC5" + + "\xC6\x03\x02\x02\x02\xC6\xC8\x03\x02\x02\x02\xC7\xC5\x03\x02\x02\x02\xC8" + + "\xCA\x07$\x02\x02\xC9\xB7\x03\x02\x02\x02\xC9\xC0\x03\x02\x02\x02\xCA" + + ".\x03\x02\x02\x02\xCB\xCD\t\x07\x02\x02\xCC\xCB\x03\x02\x02\x02\xCD\xCE" + + "\x03\x02\x02\x02\xCE\xCC\x03\x02\x02\x02\xCE\xCF\x03\x02\x02\x02\xCF\xD0" + + "\x03\x02\x02\x02\xD0\xD1\b\x18\x02\x02\xD10\x03\x02\x02\x02\xD2\xD6\x07" + + "^\x02\x02\xD3\xD7\t\b\x02\x02\xD4\xD7\x053\x1A\x02\xD5\xD7\x05m7\x02\xD6" + + "\xD3\x03\x02\x02\x02\xD6\xD4\x03\x02\x02\x02\xD6\xD5\x03\x02\x02\x02\xD7" + + "2\x03\x02\x02\x02\xD8\xD9\x07w\x02\x02\xD9\xDA\x055\x1B\x02\xDA\xDB\x05" + + "5\x1B\x02\xDB\xDC\x055\x1B\x02\xDC\xDD\x055\x1B\x02\xDD4\x03\x02\x02\x02" + + "\xDE\xDF\t\t\x02\x02\xDF6\x03\x02\x02\x02\xE0\xE1\x07^\x02\x02\xE1\xE2" + + "\x070\x02\x02\xE28\x03\x02\x02\x02\xE3\xE4\t\n\x02\x02\xE4:\x03\x02\x02" + + "\x02\xE5\xE6\t\v\x02\x02\xE6<\x03\x02\x02\x02\xE7\xE8\t\f\x02\x02\xE8" + + ">\x03\x02\x02\x02\xE9\xEA\t\r\x02\x02\xEA@\x03\x02\x02\x02\xEB\xEC\t\x0E" + + "\x02\x02\xECB\x03\x02\x02\x02\xED\xEE\t\x0F\x02\x02\xEED\x03\x02\x02\x02" + + "\xEF\xF0\t\x10\x02\x02\xF0F\x03\x02\x02\x02\xF1\xF2\t\x11\x02\x02\xF2" + + "H\x03\x02\x02\x02\xF3\xF4\t\x12\x02\x02\xF4J\x03\x02\x02\x02\xF5\xF6\t" + + "\x13\x02\x02\xF6L\x03\x02\x02\x02\xF7\xF8\t\x14\x02\x02\xF8N\x03\x02\x02" + + "\x02\xF9\xFA\t\x15\x02\x02\xFAP\x03\x02\x02\x02\xFB\xFC\t\x16\x02\x02" + + "\xFCR\x03\x02\x02\x02\xFD\xFE\t\x17\x02\x02\xFET\x03\x02\x02\x02\xFF\u0100" + + "\t\x18\x02\x02\u0100V\x03\x02\x02\x02\u0101\u0102\t\x19\x02\x02\u0102" + + "X\x03\x02\x02\x02\u0103\u0104\t\x1A\x02\x02\u0104Z\x03\x02\x02\x02\u0105" + + "\u0106\t\x1B\x02\x02\u0106\\\x03\x02\x02\x02\u0107\u0108\t\x1C\x02\x02" + + "\u0108^\x03\x02\x02\x02\u0109\u010A\t\x1D\x02\x02\u010A`\x03\x02\x02\x02" + + "\u010B\u010C\t\x1E\x02\x02\u010Cb\x03\x02\x02\x02\u010D\u010E\t\x1F\x02" + + "\x02\u010Ed\x03\x02\x02\x02\u010F\u0110\t \x02\x02\u0110f\x03\x02\x02" + + "\x02\u0111\u0112\t!\x02\x02\u0112h\x03\x02\x02\x02\u0113\u0114\t\"\x02" + + "\x02\u0114j\x03\x02\x02\x02\u0115\u0116\t#\x02\x02\u0116l\x03\x02\x02" + + "\x02\u0117\u0118\x07#\x02\x02\u0118n\x03\x02\x02\x02\x0E\x02\xA4\xAD\xB2" + + "\xB4\xBA\xBC\xC3\xC5\xC9\xCE\xD6\x03\b\x02\x02"; + public static __ATN: ATN; + public static get _ATN(): ATN { + if (!ExpressionLexer.__ATN) { + ExpressionLexer.__ATN = new ATNDeserializer().deserialize(Utils.toCharArray(ExpressionLexer._serializedATN)); + } + + return ExpressionLexer.__ATN; + } + +} + diff --git a/src/utils/Expression/ExpressionListener.ts b/src/utils/Expression/ExpressionListener.ts new file mode 100644 index 00000000..ea467d1d --- /dev/null +++ b/src/utils/Expression/ExpressionListener.ts @@ -0,0 +1,169 @@ +// Generated from /home/josejulio/Documentos/redhat/insights/custom-policies-ui-frontend/utils/Expression.g4 by ANTLR 4.7.3-SNAPSHOT + + +import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener"; + +import { ExpressionContext } from "./ExpressionParser"; +import { ObjectContext } from "./ExpressionParser"; +import { ExprContext } from "./ExpressionParser"; +import { Logical_operatorContext } from "./ExpressionParser"; +import { Boolean_operatorContext } from "./ExpressionParser"; +import { Numeric_compare_operatorContext } from "./ExpressionParser"; +import { String_compare_operatorContext } from "./ExpressionParser"; +import { Array_operatorContext } from "./ExpressionParser"; +import { ArrayContext } from "./ExpressionParser"; +import { Numerical_valueContext } from "./ExpressionParser"; +import { ValueContext } from "./ExpressionParser"; +import { Negative_exprContext } from "./ExpressionParser"; +import { KeyContext } from "./ExpressionParser"; + + +/** + * This interface defines a complete listener for a parse tree produced by + * `ExpressionParser`. + */ +export interface ExpressionListener extends ParseTreeListener { + /** + * Enter a parse tree produced by `ExpressionParser.expression`. + * @param ctx the parse tree + */ + enterExpression?: (ctx: ExpressionContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.expression`. + * @param ctx the parse tree + */ + exitExpression?: (ctx: ExpressionContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.object`. + * @param ctx the parse tree + */ + enterObject?: (ctx: ObjectContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.object`. + * @param ctx the parse tree + */ + exitObject?: (ctx: ObjectContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.expr`. + * @param ctx the parse tree + */ + enterExpr?: (ctx: ExprContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.expr`. + * @param ctx the parse tree + */ + exitExpr?: (ctx: ExprContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.logical_operator`. + * @param ctx the parse tree + */ + enterLogical_operator?: (ctx: Logical_operatorContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.logical_operator`. + * @param ctx the parse tree + */ + exitLogical_operator?: (ctx: Logical_operatorContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.boolean_operator`. + * @param ctx the parse tree + */ + enterBoolean_operator?: (ctx: Boolean_operatorContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.boolean_operator`. + * @param ctx the parse tree + */ + exitBoolean_operator?: (ctx: Boolean_operatorContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.numeric_compare_operator`. + * @param ctx the parse tree + */ + enterNumeric_compare_operator?: (ctx: Numeric_compare_operatorContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.numeric_compare_operator`. + * @param ctx the parse tree + */ + exitNumeric_compare_operator?: (ctx: Numeric_compare_operatorContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.string_compare_operator`. + * @param ctx the parse tree + */ + enterString_compare_operator?: (ctx: String_compare_operatorContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.string_compare_operator`. + * @param ctx the parse tree + */ + exitString_compare_operator?: (ctx: String_compare_operatorContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.array_operator`. + * @param ctx the parse tree + */ + enterArray_operator?: (ctx: Array_operatorContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.array_operator`. + * @param ctx the parse tree + */ + exitArray_operator?: (ctx: Array_operatorContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.array`. + * @param ctx the parse tree + */ + enterArray?: (ctx: ArrayContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.array`. + * @param ctx the parse tree + */ + exitArray?: (ctx: ArrayContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.numerical_value`. + * @param ctx the parse tree + */ + enterNumerical_value?: (ctx: Numerical_valueContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.numerical_value`. + * @param ctx the parse tree + */ + exitNumerical_value?: (ctx: Numerical_valueContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.value`. + * @param ctx the parse tree + */ + enterValue?: (ctx: ValueContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.value`. + * @param ctx the parse tree + */ + exitValue?: (ctx: ValueContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.negative_expr`. + * @param ctx the parse tree + */ + enterNegative_expr?: (ctx: Negative_exprContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.negative_expr`. + * @param ctx the parse tree + */ + exitNegative_expr?: (ctx: Negative_exprContext) => void; + + /** + * Enter a parse tree produced by `ExpressionParser.key`. + * @param ctx the parse tree + */ + enterKey?: (ctx: KeyContext) => void; + /** + * Exit a parse tree produced by `ExpressionParser.key`. + * @param ctx the parse tree + */ + exitKey?: (ctx: KeyContext) => void; +} + diff --git a/src/utils/Expression/ExpressionParser.ts b/src/utils/Expression/ExpressionParser.ts new file mode 100644 index 00000000..eee5444f --- /dev/null +++ b/src/utils/Expression/ExpressionParser.ts @@ -0,0 +1,1189 @@ +// Generated from /home/josejulio/Documentos/redhat/insights/custom-policies-ui-frontend/utils/Expression.g4 by ANTLR 4.7.3-SNAPSHOT + + +import { ATN } from "antlr4ts/atn/ATN"; +import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer"; +import { FailedPredicateException } from "antlr4ts/FailedPredicateException"; +import { NotNull } from "antlr4ts/Decorators"; +import { NoViableAltException } from "antlr4ts/NoViableAltException"; +import { Override } from "antlr4ts/Decorators"; +import { Parser } from "antlr4ts/Parser"; +import { ParserRuleContext } from "antlr4ts/ParserRuleContext"; +import { ParserATNSimulator } from "antlr4ts/atn/ParserATNSimulator"; +import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener"; +import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor"; +import { RecognitionException } from "antlr4ts/RecognitionException"; +import { RuleContext } from "antlr4ts/RuleContext"; +//import { RuleVersion } from "antlr4ts/RuleVersion"; +import { TerminalNode } from "antlr4ts/tree/TerminalNode"; +import { Token } from "antlr4ts/Token"; +import { TokenStream } from "antlr4ts/TokenStream"; +import { Vocabulary } from "antlr4ts/Vocabulary"; +import { VocabularyImpl } from "antlr4ts/VocabularyImpl"; + +import * as Utils from "antlr4ts/misc/Utils"; + +import { ExpressionListener } from "./ExpressionListener"; +import { ExpressionVisitor } from "./ExpressionVisitor"; + + +export class ExpressionParser extends Parser { + public static readonly T__0 = 1; + public static readonly T__1 = 2; + public static readonly T__2 = 3; + public static readonly T__3 = 4; + public static readonly T__4 = 5; + public static readonly OR = 6; + public static readonly AND = 7; + public static readonly NOT = 8; + public static readonly EQUAL = 9; + public static readonly NOTEQUAL = 10; + public static readonly CONTAINS = 11; + public static readonly NEG = 12; + public static readonly GT = 13; + public static readonly GTE = 14; + public static readonly LT = 15; + public static readonly LTE = 16; + public static readonly IN = 17; + public static readonly NUMBER = 18; + public static readonly FLOAT = 19; + public static readonly INTEGER = 20; + public static readonly SIMPLETEXT = 21; + public static readonly STRING = 22; + public static readonly WS = 23; + public static readonly RULE_expression = 0; + public static readonly RULE_object = 1; + public static readonly RULE_expr = 2; + public static readonly RULE_logical_operator = 3; + public static readonly RULE_boolean_operator = 4; + public static readonly RULE_numeric_compare_operator = 5; + public static readonly RULE_string_compare_operator = 6; + public static readonly RULE_array_operator = 7; + public static readonly RULE_array = 8; + public static readonly RULE_numerical_value = 9; + public static readonly RULE_value = 10; + public static readonly RULE_negative_expr = 11; + public static readonly RULE_key = 12; + // tslint:disable:no-trailing-whitespace + public static readonly ruleNames: string[] = [ + "expression", "object", "expr", "logical_operator", "boolean_operator", + "numeric_compare_operator", "string_compare_operator", "array_operator", + "array", "numerical_value", "value", "negative_expr", "key", + ]; + + private static readonly _LITERAL_NAMES: Array = [ + undefined, "'('", "')'", "'['", "','", "']'", undefined, undefined, undefined, + "'='", "'!='", undefined, undefined, "'>'", "'>='", "'<'", "'<='", + ]; + private static readonly _SYMBOLIC_NAMES: Array = [ + undefined, undefined, undefined, undefined, undefined, undefined, "OR", + "AND", "NOT", "EQUAL", "NOTEQUAL", "CONTAINS", "NEG", "GT", "GTE", "LT", + "LTE", "IN", "NUMBER", "FLOAT", "INTEGER", "SIMPLETEXT", "STRING", "WS", + ]; + public static readonly VOCABULARY: Vocabulary = new VocabularyImpl(ExpressionParser._LITERAL_NAMES, ExpressionParser._SYMBOLIC_NAMES, []); + + // @Override + // @NotNull + public get vocabulary(): Vocabulary { + return ExpressionParser.VOCABULARY; + } + // tslint:enable:no-trailing-whitespace + + // @Override + public get grammarFileName(): string { return "Expression.g4"; } + + // @Override + public get ruleNames(): string[] { return ExpressionParser.ruleNames; } + + // @Override + public get serializedATN(): string { return ExpressionParser._serializedATN; } + + constructor(input: TokenStream) { + super(input); + this._interp = new ParserATNSimulator(ExpressionParser._ATN, this); + } + // @RuleVersion(0) + public expression(): ExpressionContext { + let _localctx: ExpressionContext = new ExpressionContext(this._ctx, this.state); + this.enterRule(_localctx, 0, ExpressionParser.RULE_expression); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 26; + this.object(0); + this.state = 27; + this.match(ExpressionParser.EOF); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + + public object(): ObjectContext; + public object(_p: number): ObjectContext; + // @RuleVersion(0) + public object(_p?: number): ObjectContext { + if (_p === undefined) { + _p = 0; + } + + let _parentctx: ParserRuleContext = this._ctx; + let _parentState: number = this.state; + let _localctx: ObjectContext = new ObjectContext(this._ctx, _parentState); + let _prevctx: ObjectContext = _localctx; + let _startState: number = 2; + this.enterRecursionRule(_localctx, 2, ExpressionParser.RULE_object, _p); + try { + let _alt: number; + this.enterOuterAlt(_localctx, 1); + { + this.state = 38; + this._errHandler.sync(this); + switch (this._input.LA(1)) { + case ExpressionParser.NOT: + case ExpressionParser.NEG: + { + this.state = 30; + this.negative_expr(); + this.state = 31; + this.object(4); + } + break; + case ExpressionParser.SIMPLETEXT: + { + this.state = 33; + this.expr(); + } + break; + case ExpressionParser.T__0: + { + this.state = 34; + this.match(ExpressionParser.T__0); + this.state = 35; + this.object(0); + this.state = 36; + this.match(ExpressionParser.T__1); + } + break; + default: + throw new NoViableAltException(this); + } + this._ctx._stop = this._input.tryLT(-1); + this.state = 46; + this._errHandler.sync(this); + _alt = this.interpreter.adaptivePredict(this._input, 1, this._ctx); + while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { + if (_alt === 1) { + if (this._parseListeners != null) { + this.triggerExitRuleEvent(); + } + _prevctx = _localctx; + { + { + _localctx = new ObjectContext(_parentctx, _parentState); + this.pushNewRecursionContext(_localctx, _startState, ExpressionParser.RULE_object); + this.state = 40; + if (!(this.precpred(this._ctx, 1))) { + throw new FailedPredicateException(this, "this.precpred(this._ctx, 1)"); + } + this.state = 41; + this.logical_operator(); + this.state = 42; + this.object(2); + } + } + } + this.state = 48; + this._errHandler.sync(this); + _alt = this.interpreter.adaptivePredict(this._input, 1, this._ctx); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.unrollRecursionContexts(_parentctx); + } + return _localctx; + } + // @RuleVersion(0) + public expr(): ExprContext { + let _localctx: ExprContext = new ExprContext(this._ctx, this.state); + this.enterRule(_localctx, 4, ExpressionParser.RULE_expr); + try { + this.state = 70; + this._errHandler.sync(this); + switch ( this.interpreter.adaptivePredict(this._input, 2, this._ctx) ) { + case 1: + this.enterOuterAlt(_localctx, 1); + { + this.state = 49; + this.key(); + } + break; + + case 2: + this.enterOuterAlt(_localctx, 2); + { + this.state = 50; + this.key(); + this.state = 51; + this.boolean_operator(); + this.state = 52; + this.value(); + } + break; + + case 3: + this.enterOuterAlt(_localctx, 3); + { + this.state = 54; + this.key(); + this.state = 55; + this.numeric_compare_operator(); + this.state = 56; + this.numerical_value(); + } + break; + + case 4: + this.enterOuterAlt(_localctx, 4); + { + this.state = 58; + this.key(); + this.state = 59; + this.string_compare_operator(); + this.state = 60; + this.array(); + } + break; + + case 5: + this.enterOuterAlt(_localctx, 5); + { + this.state = 62; + this.key(); + this.state = 63; + this.string_compare_operator(); + this.state = 64; + this.value(); + } + break; + + case 6: + this.enterOuterAlt(_localctx, 6); + { + this.state = 66; + this.key(); + this.state = 67; + this.array_operator(); + this.state = 68; + this.array(); + } + break; + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public logical_operator(): Logical_operatorContext { + let _localctx: Logical_operatorContext = new Logical_operatorContext(this._ctx, this.state); + this.enterRule(_localctx, 6, ExpressionParser.RULE_logical_operator); + let _la: number; + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 72; + _la = this._input.LA(1); + if (!(_la === ExpressionParser.OR || _la === ExpressionParser.AND)) { + this._errHandler.recoverInline(this); + } else { + if (this._input.LA(1) === Token.EOF) { + this.matchedEOF = true; + } + + this._errHandler.reportMatch(this); + this.consume(); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public boolean_operator(): Boolean_operatorContext { + let _localctx: Boolean_operatorContext = new Boolean_operatorContext(this._ctx, this.state); + this.enterRule(_localctx, 8, ExpressionParser.RULE_boolean_operator); + let _la: number; + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 74; + _la = this._input.LA(1); + if (!(_la === ExpressionParser.EQUAL || _la === ExpressionParser.NOTEQUAL)) { + this._errHandler.recoverInline(this); + } else { + if (this._input.LA(1) === Token.EOF) { + this.matchedEOF = true; + } + + this._errHandler.reportMatch(this); + this.consume(); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public numeric_compare_operator(): Numeric_compare_operatorContext { + let _localctx: Numeric_compare_operatorContext = new Numeric_compare_operatorContext(this._ctx, this.state); + this.enterRule(_localctx, 10, ExpressionParser.RULE_numeric_compare_operator); + let _la: number; + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 76; + _la = this._input.LA(1); + if (!((((_la) & ~0x1F) === 0 && ((1 << _la) & ((1 << ExpressionParser.GT) | (1 << ExpressionParser.GTE) | (1 << ExpressionParser.LT) | (1 << ExpressionParser.LTE))) !== 0))) { + this._errHandler.recoverInline(this); + } else { + if (this._input.LA(1) === Token.EOF) { + this.matchedEOF = true; + } + + this._errHandler.reportMatch(this); + this.consume(); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public string_compare_operator(): String_compare_operatorContext { + let _localctx: String_compare_operatorContext = new String_compare_operatorContext(this._ctx, this.state); + this.enterRule(_localctx, 12, ExpressionParser.RULE_string_compare_operator); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 78; + this.match(ExpressionParser.CONTAINS); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public array_operator(): Array_operatorContext { + let _localctx: Array_operatorContext = new Array_operatorContext(this._ctx, this.state); + this.enterRule(_localctx, 14, ExpressionParser.RULE_array_operator); + let _la: number; + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 80; + _la = this._input.LA(1); + if (!(_la === ExpressionParser.CONTAINS || _la === ExpressionParser.IN)) { + this._errHandler.recoverInline(this); + } else { + if (this._input.LA(1) === Token.EOF) { + this.matchedEOF = true; + } + + this._errHandler.reportMatch(this); + this.consume(); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public array(): ArrayContext { + let _localctx: ArrayContext = new ArrayContext(this._ctx, this.state); + this.enterRule(_localctx, 16, ExpressionParser.RULE_array); + let _la: number; + try { + this.state = 95; + this._errHandler.sync(this); + switch ( this.interpreter.adaptivePredict(this._input, 4, this._ctx) ) { + case 1: + this.enterOuterAlt(_localctx, 1); + { + this.state = 82; + this.match(ExpressionParser.T__2); + this.state = 83; + this.value(); + this.state = 88; + this._errHandler.sync(this); + _la = this._input.LA(1); + while (_la === ExpressionParser.T__3) { + { + { + this.state = 84; + this.match(ExpressionParser.T__3); + this.state = 85; + this.value(); + } + } + this.state = 90; + this._errHandler.sync(this); + _la = this._input.LA(1); + } + this.state = 91; + this.match(ExpressionParser.T__4); + } + break; + + case 2: + this.enterOuterAlt(_localctx, 2); + { + this.state = 93; + this.match(ExpressionParser.T__2); + this.state = 94; + this.match(ExpressionParser.T__4); + } + break; + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public numerical_value(): Numerical_valueContext { + let _localctx: Numerical_valueContext = new Numerical_valueContext(this._ctx, this.state); + this.enterRule(_localctx, 18, ExpressionParser.RULE_numerical_value); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 97; + this.match(ExpressionParser.NUMBER); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public value(): ValueContext { + let _localctx: ValueContext = new ValueContext(this._ctx, this.state); + this.enterRule(_localctx, 20, ExpressionParser.RULE_value); + let _la: number; + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 99; + _la = this._input.LA(1); + if (!(_la === ExpressionParser.NUMBER || _la === ExpressionParser.STRING)) { + this._errHandler.recoverInline(this); + } else { + if (this._input.LA(1) === Token.EOF) { + this.matchedEOF = true; + } + + this._errHandler.reportMatch(this); + this.consume(); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public negative_expr(): Negative_exprContext { + let _localctx: Negative_exprContext = new Negative_exprContext(this._ctx, this.state); + this.enterRule(_localctx, 22, ExpressionParser.RULE_negative_expr); + let _la: number; + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 101; + _la = this._input.LA(1); + if (!(_la === ExpressionParser.NOT || _la === ExpressionParser.NEG)) { + this._errHandler.recoverInline(this); + } else { + if (this._input.LA(1) === Token.EOF) { + this.matchedEOF = true; + } + + this._errHandler.reportMatch(this); + this.consume(); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public key(): KeyContext { + let _localctx: KeyContext = new KeyContext(this._ctx, this.state); + this.enterRule(_localctx, 24, ExpressionParser.RULE_key); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 103; + this.match(ExpressionParser.SIMPLETEXT); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + + public sempred(_localctx: RuleContext, ruleIndex: number, predIndex: number): boolean { + switch (ruleIndex) { + case 1: + return this.object_sempred(_localctx as ObjectContext, predIndex); + } + return true; + } + private object_sempred(_localctx: ObjectContext, predIndex: number): boolean { + switch (predIndex) { + case 0: + return this.precpred(this._ctx, 1); + } + return true; + } + + public static readonly _serializedATN: string = + "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x03\x19l\x04\x02" + + "\t\x02\x04\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04\x06\t\x06\x04\x07" + + "\t\x07\x04\b\t\b\x04\t\t\t\x04\n\t\n\x04\v\t\v\x04\f\t\f\x04\r\t\r\x04" + + "\x0E\t\x0E\x03\x02\x03\x02\x03\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03" + + "\x03\x03\x03\x03\x03\x03\x03\x03\x03\x05\x03)\n\x03\x03\x03\x03\x03\x03" + + "\x03\x03\x03\x07\x03/\n\x03\f\x03\x0E\x032\v\x03\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x05\x04I\n\x04\x03\x05\x03\x05\x03\x06\x03\x06\x03\x07\x03\x07\x03\b" + + "\x03\b\x03\t\x03\t\x03\n\x03\n\x03\n\x03\n\x07\nY\n\n\f\n\x0E\n\\\v\n" + + "\x03\n\x03\n\x03\n\x03\n\x05\nb\n\n\x03\v\x03\v\x03\f\x03\f\x03\r\x03" + + "\r\x03\x0E\x03\x0E\x03\x0E\x02\x02\x03\x04\x0F\x02\x02\x04\x02\x06\x02" + + "\b\x02\n\x02\f\x02\x0E\x02\x10\x02\x12\x02\x14\x02\x16\x02\x18\x02\x1A" + + "\x02\x02\b\x03\x02\b\t\x03\x02\v\f\x03\x02\x0F\x12\x04\x02\r\r\x13\x13" + + "\x04\x02\x14\x14\x18\x18\x04\x02\n\n\x0E\x0E\x02h\x02\x1C\x03\x02\x02" + + "\x02\x04(\x03\x02\x02\x02\x06H\x03\x02\x02\x02\bJ\x03\x02\x02\x02\nL\x03" + + "\x02\x02\x02\fN\x03\x02\x02\x02\x0EP\x03\x02\x02\x02\x10R\x03\x02\x02" + + "\x02\x12a\x03\x02\x02\x02\x14c\x03\x02\x02\x02\x16e\x03\x02\x02\x02\x18" + + "g\x03\x02\x02\x02\x1Ai\x03\x02\x02\x02\x1C\x1D\x05\x04\x03\x02\x1D\x1E" + + "\x07\x02\x02\x03\x1E\x03\x03\x02\x02\x02\x1F \b\x03\x01\x02 !\x05\x18" + + "\r\x02!\"\x05\x04\x03\x06\")\x03\x02\x02\x02#)\x05\x06\x04\x02$%\x07\x03" + + "\x02\x02%&\x05\x04\x03\x02&\'\x07\x04\x02\x02\')\x03\x02\x02\x02(\x1F" + + "\x03\x02\x02\x02(#\x03\x02\x02\x02($\x03\x02\x02\x02)0\x03\x02\x02\x02" + + "*+\f\x03\x02\x02+,\x05\b\x05\x02,-\x05\x04\x03\x04-/\x03\x02\x02\x02." + + "*\x03\x02\x02\x02/2\x03\x02\x02\x020.\x03\x02\x02\x0201\x03\x02\x02\x02" + + "1\x05\x03\x02\x02\x0220\x03\x02\x02\x023I\x05\x1A\x0E\x0245\x05\x1A\x0E" + + "\x0256\x05\n\x06\x0267\x05\x16\f\x027I\x03\x02\x02\x0289\x05\x1A\x0E\x02" + + "9:\x05\f\x07\x02:;\x05\x14\v\x02;I\x03\x02\x02\x02<=\x05\x1A\x0E\x02=" + + ">\x05\x0E\b\x02>?\x05\x12\n\x02?I\x03\x02\x02\x02@A\x05\x1A\x0E\x02AB" + + "\x05\x0E\b\x02BC\x05\x16\f\x02CI\x03\x02\x02\x02DE\x05\x1A\x0E\x02EF\x05" + + "\x10\t\x02FG\x05\x12\n\x02GI\x03\x02\x02\x02H3\x03\x02\x02\x02H4\x03\x02" + + "\x02\x02H8\x03\x02\x02\x02H<\x03\x02\x02\x02H@\x03\x02\x02\x02HD\x03\x02" + + "\x02\x02I\x07\x03\x02\x02\x02JK\t\x02\x02\x02K\t\x03\x02\x02\x02LM\t\x03" + + "\x02\x02M\v\x03\x02\x02\x02NO\t\x04\x02\x02O\r\x03\x02\x02\x02PQ\x07\r" + + "\x02\x02Q\x0F\x03\x02\x02\x02RS\t\x05\x02\x02S\x11\x03\x02\x02\x02TU\x07" + + "\x05\x02\x02UZ\x05\x16\f\x02VW\x07\x06\x02\x02WY\x05\x16\f\x02XV\x03\x02" + + "\x02\x02Y\\\x03\x02\x02\x02ZX\x03\x02\x02\x02Z[\x03\x02\x02\x02[]\x03" + + "\x02\x02\x02\\Z\x03\x02\x02\x02]^\x07\x07\x02\x02^b\x03\x02\x02\x02_`" + + "\x07\x05\x02\x02`b\x07\x07\x02\x02aT\x03\x02\x02\x02a_\x03\x02\x02\x02" + + "b\x13\x03\x02\x02\x02cd\x07\x14\x02\x02d\x15\x03\x02\x02\x02ef\t\x06\x02" + + "\x02f\x17\x03\x02\x02\x02gh\t\x07\x02\x02h\x19\x03\x02\x02\x02ij\x07\x17" + + "\x02\x02j\x1B\x03\x02\x02\x02\x07(0HZa"; + public static __ATN: ATN; + public static get _ATN(): ATN { + if (!ExpressionParser.__ATN) { + ExpressionParser.__ATN = new ATNDeserializer().deserialize(Utils.toCharArray(ExpressionParser._serializedATN)); + } + + return ExpressionParser.__ATN; + } + +} + +export class ExpressionContext extends ParserRuleContext { + public object(): ObjectContext { + return this.getRuleContext(0, ObjectContext); + } + public EOF(): TerminalNode { return this.getToken(ExpressionParser.EOF, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_expression; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterExpression) { + listener.enterExpression(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitExpression) { + listener.exitExpression(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitExpression) { + return visitor.visitExpression(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class ObjectContext extends ParserRuleContext { + public negative_expr(): Negative_exprContext | undefined { + return this.tryGetRuleContext(0, Negative_exprContext); + } + public object(): ObjectContext[]; + public object(i: number): ObjectContext; + public object(i?: number): ObjectContext | ObjectContext[] { + if (i === undefined) { + return this.getRuleContexts(ObjectContext); + } else { + return this.getRuleContext(i, ObjectContext); + } + } + public expr(): ExprContext | undefined { + return this.tryGetRuleContext(0, ExprContext); + } + public logical_operator(): Logical_operatorContext | undefined { + return this.tryGetRuleContext(0, Logical_operatorContext); + } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_object; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterObject) { + listener.enterObject(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitObject) { + listener.exitObject(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitObject) { + return visitor.visitObject(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class ExprContext extends ParserRuleContext { + public key(): KeyContext { + return this.getRuleContext(0, KeyContext); + } + public boolean_operator(): Boolean_operatorContext | undefined { + return this.tryGetRuleContext(0, Boolean_operatorContext); + } + public value(): ValueContext | undefined { + return this.tryGetRuleContext(0, ValueContext); + } + public numeric_compare_operator(): Numeric_compare_operatorContext | undefined { + return this.tryGetRuleContext(0, Numeric_compare_operatorContext); + } + public numerical_value(): Numerical_valueContext | undefined { + return this.tryGetRuleContext(0, Numerical_valueContext); + } + public string_compare_operator(): String_compare_operatorContext | undefined { + return this.tryGetRuleContext(0, String_compare_operatorContext); + } + public array(): ArrayContext | undefined { + return this.tryGetRuleContext(0, ArrayContext); + } + public array_operator(): Array_operatorContext | undefined { + return this.tryGetRuleContext(0, Array_operatorContext); + } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_expr; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterExpr) { + listener.enterExpr(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitExpr) { + listener.exitExpr(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitExpr) { + return visitor.visitExpr(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class Logical_operatorContext extends ParserRuleContext { + public AND(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.AND, 0); } + public OR(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.OR, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_logical_operator; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterLogical_operator) { + listener.enterLogical_operator(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitLogical_operator) { + listener.exitLogical_operator(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitLogical_operator) { + return visitor.visitLogical_operator(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class Boolean_operatorContext extends ParserRuleContext { + public EQUAL(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.EQUAL, 0); } + public NOTEQUAL(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.NOTEQUAL, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_boolean_operator; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterBoolean_operator) { + listener.enterBoolean_operator(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitBoolean_operator) { + listener.exitBoolean_operator(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitBoolean_operator) { + return visitor.visitBoolean_operator(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class Numeric_compare_operatorContext extends ParserRuleContext { + public GT(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.GT, 0); } + public GTE(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.GTE, 0); } + public LT(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.LT, 0); } + public LTE(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.LTE, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_numeric_compare_operator; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterNumeric_compare_operator) { + listener.enterNumeric_compare_operator(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitNumeric_compare_operator) { + listener.exitNumeric_compare_operator(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitNumeric_compare_operator) { + return visitor.visitNumeric_compare_operator(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class String_compare_operatorContext extends ParserRuleContext { + public CONTAINS(): TerminalNode { return this.getToken(ExpressionParser.CONTAINS, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_string_compare_operator; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterString_compare_operator) { + listener.enterString_compare_operator(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitString_compare_operator) { + listener.exitString_compare_operator(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitString_compare_operator) { + return visitor.visitString_compare_operator(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class Array_operatorContext extends ParserRuleContext { + public IN(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.IN, 0); } + public CONTAINS(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.CONTAINS, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_array_operator; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterArray_operator) { + listener.enterArray_operator(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitArray_operator) { + listener.exitArray_operator(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitArray_operator) { + return visitor.visitArray_operator(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class ArrayContext extends ParserRuleContext { + public value(): ValueContext[]; + public value(i: number): ValueContext; + public value(i?: number): ValueContext | ValueContext[] { + if (i === undefined) { + return this.getRuleContexts(ValueContext); + } else { + return this.getRuleContext(i, ValueContext); + } + } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_array; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterArray) { + listener.enterArray(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitArray) { + listener.exitArray(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitArray) { + return visitor.visitArray(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class Numerical_valueContext extends ParserRuleContext { + public NUMBER(): TerminalNode { return this.getToken(ExpressionParser.NUMBER, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_numerical_value; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterNumerical_value) { + listener.enterNumerical_value(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitNumerical_value) { + listener.exitNumerical_value(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitNumerical_value) { + return visitor.visitNumerical_value(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class ValueContext extends ParserRuleContext { + public NUMBER(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.NUMBER, 0); } + public STRING(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.STRING, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_value; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterValue) { + listener.enterValue(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitValue) { + listener.exitValue(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitValue) { + return visitor.visitValue(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class Negative_exprContext extends ParserRuleContext { + public NEG(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.NEG, 0); } + public NOT(): TerminalNode | undefined { return this.tryGetToken(ExpressionParser.NOT, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_negative_expr; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterNegative_expr) { + listener.enterNegative_expr(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitNegative_expr) { + listener.exitNegative_expr(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitNegative_expr) { + return visitor.visitNegative_expr(this); + } else { + return visitor.visitChildren(this); + } + } +} + + +export class KeyContext extends ParserRuleContext { + public SIMPLETEXT(): TerminalNode { return this.getToken(ExpressionParser.SIMPLETEXT, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return ExpressionParser.RULE_key; } + // @Override + public enterRule(listener: ExpressionListener): void { + if (listener.enterKey) { + listener.enterKey(this); + } + } + // @Override + public exitRule(listener: ExpressionListener): void { + if (listener.exitKey) { + listener.exitKey(this); + } + } + // @Override + public accept(visitor: ExpressionVisitor): Result { + if (visitor.visitKey) { + return visitor.visitKey(this); + } else { + return visitor.visitChildren(this); + } + } +} + + diff --git a/src/utils/Expression/ExpressionVisitor.ts b/src/utils/Expression/ExpressionVisitor.ts new file mode 100644 index 00000000..5a2f244f --- /dev/null +++ b/src/utils/Expression/ExpressionVisitor.ts @@ -0,0 +1,120 @@ +// Generated from /home/josejulio/Documentos/redhat/insights/custom-policies-ui-frontend/utils/Expression.g4 by ANTLR 4.7.3-SNAPSHOT + + +import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor"; + +import { ExpressionContext } from "./ExpressionParser"; +import { ObjectContext } from "./ExpressionParser"; +import { ExprContext } from "./ExpressionParser"; +import { Logical_operatorContext } from "./ExpressionParser"; +import { Boolean_operatorContext } from "./ExpressionParser"; +import { Numeric_compare_operatorContext } from "./ExpressionParser"; +import { String_compare_operatorContext } from "./ExpressionParser"; +import { Array_operatorContext } from "./ExpressionParser"; +import { ArrayContext } from "./ExpressionParser"; +import { Numerical_valueContext } from "./ExpressionParser"; +import { ValueContext } from "./ExpressionParser"; +import { Negative_exprContext } from "./ExpressionParser"; +import { KeyContext } from "./ExpressionParser"; + + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by `ExpressionParser`. + * + * @param The return type of the visit operation. Use `void` for + * operations with no return type. + */ +export interface ExpressionVisitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by `ExpressionParser.expression`. + * @param ctx the parse tree + * @return the visitor result + */ + visitExpression?: (ctx: ExpressionContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.object`. + * @param ctx the parse tree + * @return the visitor result + */ + visitObject?: (ctx: ObjectContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.expr`. + * @param ctx the parse tree + * @return the visitor result + */ + visitExpr?: (ctx: ExprContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.logical_operator`. + * @param ctx the parse tree + * @return the visitor result + */ + visitLogical_operator?: (ctx: Logical_operatorContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.boolean_operator`. + * @param ctx the parse tree + * @return the visitor result + */ + visitBoolean_operator?: (ctx: Boolean_operatorContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.numeric_compare_operator`. + * @param ctx the parse tree + * @return the visitor result + */ + visitNumeric_compare_operator?: (ctx: Numeric_compare_operatorContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.string_compare_operator`. + * @param ctx the parse tree + * @return the visitor result + */ + visitString_compare_operator?: (ctx: String_compare_operatorContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.array_operator`. + * @param ctx the parse tree + * @return the visitor result + */ + visitArray_operator?: (ctx: Array_operatorContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.array`. + * @param ctx the parse tree + * @return the visitor result + */ + visitArray?: (ctx: ArrayContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.numerical_value`. + * @param ctx the parse tree + * @return the visitor result + */ + visitNumerical_value?: (ctx: Numerical_valueContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.value`. + * @param ctx the parse tree + * @return the visitor result + */ + visitValue?: (ctx: ValueContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.negative_expr`. + * @param ctx the parse tree + * @return the visitor result + */ + visitNegative_expr?: (ctx: Negative_exprContext) => Result; + + /** + * Visit a parse tree produced by `ExpressionParser.key`. + * @param ctx the parse tree + * @return the visitor result + */ + visitKey?: (ctx: KeyContext) => Result; +} + diff --git a/tsconfig.json b/tsconfig.json index 66598249..97c85a56 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "module": "commonjs", - "target": "es5", + "target": "es6", "allowJs": true, "checkJs": false, "jsx": "react", @@ -13,7 +13,8 @@ "strict": true, "moduleResolution": "node", "esModuleInterop": true, - "noImplicitAny": false + "noImplicitAny": false, + "sourceMap": true }, "include": [ "./src/**/*" diff --git a/yarn.lock b/yarn.lock index f54477e9..c9b41384 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2199,6 +2199,16 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" +antlr4ts-cli@^0.5.0-alpha.3: + version "0.5.0-alpha.3" + resolved "https://registry.yarnpkg.com/antlr4ts-cli/-/antlr4ts-cli-0.5.0-alpha.3.tgz#1f581b2a3c840d3921a2f3b1e739e48c7e7c18cd" + integrity sha512-i6oyxfaXU6qnw4HgyeSIsOLlsvT7zU3vmenoJKFNVFP1QNodtJMZYpnyxc8TmOFpJs7fEoWanLavSSDEmcCZBQ== + +antlr4ts@^0.5.0-alpha.3: + version "0.5.0-alpha.3" + resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.3.tgz#fa6d39d88d6b96341a8afef45867af9abcb38766" + integrity sha512-La89tKkGcHFIVuruv4Bm1esc3zLmES2NOTEwwNS1pudz+zx/0FNqQeUu9p48i9/QHKPVqjN87LB+q3buTg7oDQ== + any-promise@^1.0.0, any-promise@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" @@ -5278,17 +5288,17 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" -formik@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/formik/-/formik-2.0.6.tgz#e22e3452399a69ad057ba9828ba8fb0d2319df53" - integrity sha512-x2fC80v8AIrGgpxWrLqKaK9hdV8WX4OSLK+Fr5lclqExA59NCuxdB3WiuxJQc9/g043BmfTIuaILrV9Wq0MPVw== +formik@2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/formik/-/formik-2.1.4.tgz#8deef07ec845ea98f75e03da4aad7aab4ac46570" + integrity sha512-oKz8S+yQBzuQVSEoxkqqJrKQS5XJASWGVn6mrs+oTWrBoHgByVwwI1qHiVc9GKDpZBU9vAxXYAKz2BvujlwunA== dependencies: deepmerge "^2.1.1" hoist-non-react-statics "^3.3.0" lodash "^4.17.14" lodash-es "^4.17.14" react-fast-compare "^2.0.1" - scheduler "^0.17.0" + scheduler "^0.18.0" tiny-warning "^1.0.2" tslib "^1.10.0" @@ -10284,6 +10294,14 @@ scheduler@^0.17.0: loose-envify "^1.1.0" object-assign "^4.1.1" +scheduler@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4" + integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + schema-utils@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"