We were talking about Expressions and ExpressionsVisitors earlier. ExpressionVisitors are a robust and encapsulated way to define expression tree processing logic created as a new JavaScript class, ready to be used by other parts of the system or to be subclassed for whatever reasons.
However creating a full-featured visitor class might not always be an appropriate way, for example when we want to do some simple crawling on the tree and don’t want to have an extra class for that. Or want to process/modify a specific tree? Visitors by default must not modify the tree on which they operate, instead must provide a new, modified tree from the original, and leave the original intact…
Enter ExpressionsMonitor to help us! ExpressionMonitor provides you with a way to define tree processing logic in simple functions (you don’t need a class to encapsulate them) plus let’s you monitor and mutate and not just visit the expressions.
To use an ExpressionMonitor you need an expression instance. ExpressionNode defines the monitor function that takes one parameter: and object/instance with specific method names!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
$C(<span class="str">'$data.types.storageProviders.sqLite.SQLiteCompiler'</span>, <span class="kwrd">null</span>, <span class="kwrd">null</span>, { compile: <span class="kwrd">function</span> (query) { <span class="rem">/// <param name="query" type="$data.Query" /></span> <span class="kwrd">var</span> expression = query.expression; <span class="kwrd">var</span> res = expression.monitor({ VisitExpressionNode: <span class="kwrd">function</span> (expression, context) { <span class="rem">//gets called BEFORE each item gets visited. Returning an expression is mantadory.</span> <span class="rem">//MODIFICATION to the expression is NOT ALLOWED.</span> console.log(<span class="str">"visitor: "</span> + expression.getType().name); <span class="kwrd">return</span> expression; }, VisitSimpleBinaryExpression: <span class="kwrd">function</span> (expression, context) { <span class="rem">//gets called BEFORE each item gets visited. Returning an expression is mantadory.</span> <span class="rem">//MODIFICATION to the expression is NOT ALLOWED.</span> console.log(<span class="str">"visitor: "</span> + expression.getType().name); <span class="kwrd">return</span> expression; }, MonitorExpressionNode: <span class="kwrd">function</span> (expression, context) { <span class="rem">//gets called AFTER each item is visited. Return value if any is discarded.</span> <span class="rem">//MODIFICATION to the expression is NOT ALLOWED.</span> console.log(<span class="str">"monitor: "</span> + expression.getType().name); }, MonitorEntitySetExpression: <span class="kwrd">function</span> (expression, context) { <span class="rem">//gets called AFTER the given type is visited.</span> <span class="rem">//MODIFICATION to the expression is NOT ALLOWED.</span> context.sets.push(expression); }, MutateExpressionNode: <span class="kwrd">function</span> (expression, context) { <span class="rem">//gets called AFTER each type is visited and monitored</span> <span class="rem">//returning a value is optional and will replce the result in the output</span> <span class="rem">//modification to the expression is allowed.</span> }, MutateEntitySetExpression: <span class="kwrd">function</span> (expression, context) { <span class="rem">//gets called AFTER the given type is visited and monitored</span> <span class="rem">//returning a value is optional and will replce the result in the output</span> <span class="rem">//modification to the expression is allowed.</span> } }, { sets: [] }); |