Henri Biestro created JEXL-474:
----------------------------------

             Summary: Declare antish variable names at parse time through 
JexlFeatures
                 Key: JEXL-474
                 URL: https://issues.apache.org/jira/browse/JEXL-474
             Project: Commons JEXL
          Issue Type: Improvement
    Affects Versions: 3.7.1
            Reporter: Henri Biestro
            Assignee: Henri Biestro
             Fix For: 3.7.2



  Antish variables (global variables whose names contain dots, like {{x.y.z}}) 
are currently solved at runtime:
  for each reference rooted on an undefined global, the interpreter builds the 
successive dotted names and
  queries the context for each of them. This has a cost on every evaluation and 
makes some behaviors
  ambiguous, in particular with respect to side effects: at parse time, {{x.y = 
1}} may either set the
  property {{y}} of {{x}} or create the global {{x.y}}.

  This improvement allows declaring antish variable names at parse time:

  {code:java}
  JexlFeatures features = JexlFeatures.createDefault()
      .antishTest(JexlFeatures.namePatterns(Arrays.asList("x.y", "build.*")));
  JexlEngine jexl = new JexlBuilder().features(features).create();
  {code}

  When a predicate is declared:
  * the parser rewrites references rooted on a global variable so that the 
longest dotted prefix
    satisfying the predicate is a single variable; {{x.y.z}} becomes the 
variable {{x.y}} followed by the
    property access {{.z}}. A local variable root, a safe navigation segment 
({{?.}}) or an expression
    segment (back-quoted) stops the rewrite;
  * all antish names are known beforehand, runtime antish resolution is 
disabled for the engine,
    regardless of the {{JexlOptions.setAntish}} option (including options 
provided by the context
    or pragmas);
  * with {{sideEffectGlobal(false)}}, only assigning a global variable is a 
global side effect:
    {{x.y = 1}} (x.y declared) or {{x = 1}} are rejected while {{x.y.z = 1}} or 
{{x[0] = 1}} (assigning a
    property of a global variable value) are allowed. Without declared names, 
the current behavior is
    kept since any property assignment on a global may create an antish 
variable.

  Only the engine features determine whether runtime antish is disabled; a 
predicate passed only through
  {{JexlEngine.createScript(JexlFeatures, ...)}} rewrites references but leaves 
runtime resolution enabled.

  {{JexlFeatures.namePatterns(Collection)}} creates a name test from exact 
names and {{prefix.*}} patterns;
  {{pragmaPatterns}} now delegates to it.

  Declared antish variables are significantly faster: on a loop reading and 
writing {{x.y.z}}/{{x.y.w}},
  about 10 µs/op vs 41 µs/op with runtime resolution (JMH, 
InterpreterBenchmark).

  Without a declared predicate (the default), behavior is unchanged.




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to