com.google.clearsilver.jsilver.syntax
Class VarOptimizer

java.lang.Object
  extended by com.google.clearsilver.jsilver.syntax.analysis.AnalysisAdapter
      extended by com.google.clearsilver.jsilver.syntax.analysis.DepthFirstAdapter
          extended by com.google.clearsilver.jsilver.syntax.VarOptimizer
All Implemented Interfaces:
Analysis, Switch

public class VarOptimizer
extends DepthFirstAdapter

Recursively optimizes the syntax tree with a set of simple operations. This class currently optimizes:

String add expressions in var commands are optimized by replacing something like:

 <cs? var:a + b ?>
 
with:
 <cs? var:a ?><cs? var:b ?>
 
This avoids having to construct the intermediate result a + b at runtime and reduces runtime heap allocations.

Functions call to escaping functions are optimized by replacing them with the equivalent escaping construct. This is faster because escapers are called with the strings themselves whereas general function calls require value objects to be created.

Expressions such as:

 <cs? var:html_escape(foo) ?>
 
are turned into:
 <cs? escape:"html" ?>
 <cs? var:foo ?>
 <?cs /escape ?>
 
It also optimizes sequences of escaped expressions into a single escaped sequence.

It is important to note that these optimizations cannot be done in isolation if we want to optimize compound expressions such as:

 <cs? html_escape(foo + bar) + baz ?>
 
which is turned into:
 <cs? escape:"html" ?>
 <cs? var:foo ?>
 <cs? var:bar ?>
 <?cs /escape ?>
 <?cs var:baz ?>
 
WARNING: This class isn't strictly just an optimization and its modification of the syntax tree actually improves JSilver's behavior, bringing it more in line with ClearSilver. Consider the sequence:
 <cs? escape:"html" ?>
 <cs? var:url_escape(foo) ?>
 <?cs /escape ?>
 
In JSilver (without this optimizer being run) this would result in foo being escaped by both the html escaper and the url escaping function. However ClearSilver treats top-level escaper functions specially and foo is only escaped once by the url escaping function. The good news is that this optimization rewrites the above example to:
 <cs? escape:"html" ?>
 <cs? escape:"url" ?>
 <cs? var:foo ?>
 <?cs /escape ?>
 <?cs /escape ?>
 
which fixes the problem because the new url escaper replaces the existing html escaper (rather than combining with it). The only fly in the ointment here is the url_validate function which is treated like an escaper by ClearSilver but which does not (currently) have an escaper associated with it. This means that:
 <cs? escape:"html" ?>
 <cs? var:url_validate(foo) ?>
 <?cs /escape ?>
 
will not be rewritten by this class and will result in foo being escaped twice.


Constructor Summary
VarOptimizer(Collection<String> escaperNames)
           
 
Method Summary
 void caseAMultipleCommand(AMultipleCommand multiCommand)
           
 void caseAVarCommand(AVarCommand varCommand)
           
 
Methods inherited from class com.google.clearsilver.jsilver.syntax.analysis.DepthFirstAdapter
caseAAddExpression, caseAAltCommand, caseAAndExpression, caseAAutoescapeCommand, caseACallCommand, caseACommaExpression, caseACommentCommand, caseAContentTypeCommand, caseACsOpenPosition, caseADataCommand, caseADecimalExpression, caseADecNumberVariable, caseADefCommand, caseADescendVariable, caseADivideExpression, caseAEachCommand, caseAEqExpression, caseAEscapeCommand, caseAEvarCommand, caseAExistsExpression, caseAExpandVariable, caseAFunctionExpression, caseAGteExpression, caseAGtExpression, caseAHardIncludeCommand, caseAHardLincludeCommand, caseAHexExpression, caseAHexNumberVariable, caseAIfCommand, caseAIncludeCommand, caseAInlineCommand, caseALincludeCommand, caseALoopCommand, caseALoopIncCommand, caseALoopToCommand, caseALteExpression, caseALtExpression, caseALvarCommand, caseAModuloExpression, caseAMultiplyExpression, caseANameCommand, caseANameVariable, caseANeExpression, caseANegativeExpression, caseANoopCommand, caseANoopExpression, caseANotExpression, caseANumericAddExpression, caseANumericEqExpression, caseANumericExpression, caseANumericNeExpression, caseAOrExpression, caseASequenceExpression, caseASetCommand, caseAStringExpression, caseASubtractExpression, caseAUvarCommand, caseAVariableExpression, caseAWithCommand, caseStart, defaultIn, defaultOut, inAAddExpression, inAAltCommand, inAAndExpression, inAAutoescapeCommand, inACallCommand, inACommaExpression, inACommentCommand, inAContentTypeCommand, inACsOpenPosition, inADataCommand, inADecimalExpression, inADecNumberVariable, inADefCommand, inADescendVariable, inADivideExpression, inAEachCommand, inAEqExpression, inAEscapeCommand, inAEvarCommand, inAExistsExpression, inAExpandVariable, inAFunctionExpression, inAGteExpression, inAGtExpression, inAHardIncludeCommand, inAHardLincludeCommand, inAHexExpression, inAHexNumberVariable, inAIfCommand, inAIncludeCommand, inAInlineCommand, inALincludeCommand, inALoopCommand, inALoopIncCommand, inALoopToCommand, inALteExpression, inALtExpression, inALvarCommand, inAModuloExpression, inAMultipleCommand, inAMultiplyExpression, inANameCommand, inANameVariable, inANeExpression, inANegativeExpression, inANoopCommand, inANoopExpression, inANotExpression, inANumericAddExpression, inANumericEqExpression, inANumericExpression, inANumericNeExpression, inAOrExpression, inASequenceExpression, inASetCommand, inAStringExpression, inASubtractExpression, inAUvarCommand, inAVarCommand, inAVariableExpression, inAWithCommand, inStart, outAAddExpression, outAAltCommand, outAAndExpression, outAAutoescapeCommand, outACallCommand, outACommaExpression, outACommentCommand, outAContentTypeCommand, outACsOpenPosition, outADataCommand, outADecimalExpression, outADecNumberVariable, outADefCommand, outADescendVariable, outADivideExpression, outAEachCommand, outAEqExpression, outAEscapeCommand, outAEvarCommand, outAExistsExpression, outAExpandVariable, outAFunctionExpression, outAGteExpression, outAGtExpression, outAHardIncludeCommand, outAHardLincludeCommand, outAHexExpression, outAHexNumberVariable, outAIfCommand, outAIncludeCommand, outAInlineCommand, outALincludeCommand, outALoopCommand, outALoopIncCommand, outALoopToCommand, outALteExpression, outALtExpression, outALvarCommand, outAModuloExpression, outAMultipleCommand, outAMultiplyExpression, outANameCommand, outANameVariable, outANeExpression, outANegativeExpression, outANoopCommand, outANoopExpression, outANotExpression, outANumericAddExpression, outANumericEqExpression, outANumericExpression, outANumericNeExpression, outAOrExpression, outASequenceExpression, outASetCommand, outAStringExpression, outASubtractExpression, outAUvarCommand, outAVarCommand, outAVariableExpression, outAWithCommand, outStart
 
Methods inherited from class com.google.clearsilver.jsilver.syntax.analysis.AnalysisAdapter
caseEOF, caseTAlt, caseTAnd, caseTArgWhitespace, caseTAssignment, caseTAutoescape, caseTBang, caseTBracketClose, caseTBracketOpen, caseTCall, caseTComma, caseTCommandDelimiter, caseTComment, caseTCommentStart, caseTContentType, caseTCsClose, caseTCsOpen, caseTData, caseTDecNumber, caseTDef, caseTDollar, caseTDot, caseTEach, caseTElse, caseTElseIf, caseTEq, caseTEscape, caseTEvar, caseTGt, caseTGte, caseTHardDelimiter, caseTHash, caseTHexNumber, caseTIf, caseTInclude, caseTInline, caseTLinclude, caseTLoop, caseTLt, caseTLte, caseTLvar, caseTMinus, caseTName, caseTNe, caseTOr, caseTParenClose, caseTParenOpen, caseTPercent, caseTPlus, caseTQuestion, caseTSet, caseTSlash, caseTStar, caseTString, caseTUvar, caseTVar, caseTWith, caseTWord, defaultCase, getIn, getOut, setIn, setOut
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

VarOptimizer

public VarOptimizer(Collection<String> escaperNames)
Method Detail

caseAMultipleCommand

public void caseAMultipleCommand(AMultipleCommand multiCommand)
Specified by:
caseAMultipleCommand in interface Analysis
Overrides:
caseAMultipleCommand in class DepthFirstAdapter

caseAVarCommand

public void caseAVarCommand(AVarCommand varCommand)
Specified by:
caseAVarCommand in interface Analysis
Overrides:
caseAVarCommand in class DepthFirstAdapter


Copyright © 2010-2012 Google. All Rights Reserved.