[ 
https://issues.apache.org/jira/browse/CAMEL-24984?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18118800#comment-18118800
 ] 

Claus Ibsen commented on CAMEL-24984:
-------------------------------------

Merged in main for 4.23.0: b265af249c98 (PR #26824).

Simple now reads a {{!}} in front of a function as a negation, in a predicate 
only: {{!${body.isEmpty()}}} and {{${!body.isEmpty()}}}, grouping with {{&&}} 
and {{||}} like any other predicate. An expression is untouched, so {{Hello 
${body}!}} is still text, and the eleven operators that start with a {{!}} are 
matched before it.

> 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
>            Assignee: Claus Ibsen
>            Priority: Major
>             Fix For: 4.23.0
>
>
> 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)

Reply via email to