Claus Ibsen created CAMEL-24984:
-----------------------------------
Summary: camel-core: simple - support ! as a negation prefix in a
predicate
Key: CAMEL-24984
URL: https://issues.apache.org/jira/browse/CAMEL-24984
Project: Camel
Issue Type: Improvement
Components: camel-core
Reporter: Claus Ibsen
Simple has no boolean {{!}} prefix. {{${body != null && !body.isEmpty()}}} and
{{${body != null && !${body.isEmpty()}}}} both fail; the comparison has to be
written out as {{${body.isEmpty()} == false}}. Every language a Camel user
comes from has {{!}}, and it is one of the forms a local model writes
unprompted (seen in three separate benchmark series).
h3. Why the risk is smaller than it looks
Simple only interprets operators in *predicate* context. An expression - the
log messages people worry about - never tokenizes an operator at all:
{noformat}
"Hello ${body}! how are you" -> Hello World! how are you
"!aaa! is a weird text" -> !aaa! is a weird text
"${body} != 'x'" -> World != 'x' (even != is literal text in
an expression)
{noformat}
Quoted literals inside a predicate are also already safe, since the tokenizer
takes a quoted string as one unit: {{${body} == 'Hello!'}}, {{${body} contains
'!'}} and {{${body} != 'x!'}} all evaluate correctly today.
So the blast radius is an unquoted {{!}} at an operand position inside a
predicate.
h3. The sharp edge
A bare {{!}} has to be told apart from the nine operators that already start
with one: {{!=}}, {{!contains}}, {{!endsWith}}, {{!equals}}, {{!in}}, {{!is}},
{{!range}}, {{!regex}}, {{!startsWith}}. They are a known, finite set, so the
cases can be enumerated in tests, but the ordering logic in the tokenizer is
where a regression would hide.
h3. What it touches
# {{UnaryOperatorType}} - a NOT alongside INC and DEC.
# {{SimpleTokenizer}} - {{!}} as a token. {{evalUnary}} today requires the
previous character to be {{\}}} and the next to be whitespace, which is the
*postfix* rule for {{++}} and {{--}}; a prefix needs the inverse, so that
method has to branch per operator or a new token type is needed.
# {{UnaryExpression}} applies to the node on its left ({{acceptLeft}}) and
{{prepareUnaryExpressions}} stacks leftward; a prefix form applies to the node
on its right.
# {{createExpression}} there handles numeric {{++}}/{{--}}; NOT needs boolean
semantics and must produce a Predicate.
# {{SimpleSyntaxHints.wrapFunctions}} (CAMEL-24921) splits on {{&&}} and {{||}}
and must keep a leading {{!}} attached to its operand.
# the simple language documentation, and the message added for the unsupported
case, which would then be wrong.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)