Skip to content

Commit

Permalink
Fixed unary expression editing (#3666)
Browse files Browse the repository at this point in the history
Co-authored-by: Stefano Ricci <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 22, 2024
1 parent f686ce8 commit 8af1c81
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 24 deletions.
36 changes: 23 additions & 13 deletions webapp/components/expression/nodes/binaryOperand.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@ import * as ProcessUtils from '@core/processUtils'

import { Button } from '@webapp/components/buttons'

const { types } = Expression

const availableOperandExpressionTypes = [
Expression.types.Identifier,
Expression.types.Literal,
...(ProcessUtils.ENV.experimentalFeatures ? [Expression.types.CallExpression] : []),
types.Identifier,
types.Literal,
...(ProcessUtils.ENV.experimentalFeatures ? [types.CallExpression] : []),
]

const expressionTypeAcronymByType = {
[Expression.types.CallExpression]: 'call',
[Expression.types.Identifier]: 'var',
[Expression.types.Literal]: 'const',
[types.CallExpression]: 'call',
[types.Identifier]: 'var',
[types.Literal]: 'const',
}

const expressionGeneratorByType = {
[Expression.types.CallExpression]: () => Expression.newCall(),
[Expression.types.Identifier]: () => Expression.newIdentifier(),
[Expression.types.Literal]: () => Expression.newLiteral(),
[types.CallExpression]: () => Expression.newCall(),
[types.Identifier]: () => Expression.newIdentifier(),
[types.Literal]: () => Expression.newLiteral(),
}

const BinaryOperandExpressionTypeButton = (props) => {
Expand Down Expand Up @@ -54,6 +56,14 @@ export const BinaryOperandType = {
BinaryOperandType.isLeft = (type) => type === BinaryOperandType.left
BinaryOperandType.isRight = (type) => type === BinaryOperandType.right

const toUiOperandExpressionType = (type) => {
if (type === types.UnaryExpression) {
// unary expressions managed as literal expressions in UI
return types.Literal
}
return type
}

const BinaryOperand = (props) => {
const {
canDelete = false,
Expand All @@ -69,17 +79,17 @@ const BinaryOperand = (props) => {
} = props

const nodeOperand = node[type]
const operandExpressionType = Expression.getType(nodeOperand)
const operandExpressionType = toUiOperandExpressionType(Expression.getType(nodeOperand))
const isLeft = BinaryOperandType.isLeft(type)
const currentNodeDefIsBoolean = NodeDef.isBoolean(nodeDefCurrent)

const canOperandExpressionBeOfType = useCallback(
(expressionType) => {
switch (expressionType) {
case Expression.types.Identifier:
case Expression.types.CallExpression:
case types.Identifier:
case types.CallExpression:
return true
case Expression.types.Literal:
case types.Literal:
return !isLeft || !isBoolean || currentNodeDefIsBoolean
default:
return false
Expand Down
41 changes: 30 additions & 11 deletions webapp/components/expression/nodes/expressionNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,38 @@ import Literal from './literal'
import Logical from './logical'
import Member from './member'

const { types } = Expression

const componentFns = {
[Expression.types.Identifier]: () => Identifier,
[Expression.types.MemberExpression]: () => Member,
[Expression.types.Literal]: () => Literal,
[Expression.types.CallExpression]: () => Call,
[Expression.types.BinaryExpression]: (expressionNode) => {
[types.Identifier]: () => Identifier,
[types.MemberExpression]: () => Member,
[types.Literal]: () => Literal,
[types.CallExpression]: () => Call,
[types.BinaryExpression]: (expressionNode) => {
const { logical: logicalOperators } = Expression.operators
return [logicalOperators.or.value, logicalOperators.and.value].includes(expressionNode.operator) ? Logical : Binary
},
[Expression.types.SequenceExpression]: () => Sequence,
[types.SequenceExpression]: () => Sequence,
}

const thisExpressionNode = { type: types.Identifier, name: Expression.thisVariable }

const toUiComponentNode = (node) => {
const { type } = node
if (type === types.ThisExpression) {
return thisExpressionNode
}
if (type === types.UnaryExpression) {
// e.g. this > -1 ; -1 is a unary expression (value 1, operator -)
// in the expression editor it will be managed as a literal expression, with a value of "-1"
const { argument } = node
const { type: argumentType, value: argumentValue } = argument ?? {}
if (argumentType === types.Literal) {
const newValue = `${node.operator} ${argumentValue}`
return Expression.newLiteral(newValue)
}
}
return node
}

const ExpressionNode = (props) => {
Expand All @@ -36,11 +58,8 @@ const ExpressionNode = (props) => {
variables = null,
} = props

// transform a "this" expression into an Identifier expression
const componentNode =
node.type === Expression.types.ThisExpression
? { type: Expression.types.Identifier, name: Expression.thisVariable }
: node
const componentNode = toUiComponentNode(node)
if (!componentNode) return null

const componentFn = componentFns[componentNode.type]
const component = componentFn(componentNode)
Expand Down

0 comments on commit 8af1c81

Please sign in to comment.