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)