private QilNode CompileApplyTemplates(XslNodeEx node)
{
QilNode result;
IList<XslNode> content = node.Content;
// Calculate select expression
int varScope = _varHelper.StartVariables();
QilIterator select = _f.Let(CompileNodeSetExpression(node.Select));
_varHelper.AddVariable(select);
// Compile with-param's, they must be calculated outside the loop and
// if they are neither constant nor reference we need to cache them in Let's
for (int i = 0; i < content.Count; i++)
{
VarPar withParam = content[i] as VarPar;
if (withParam != null)
{
Debug.Assert(withParam.NodeType == XslNodeType.WithParam);
CompileWithParam(withParam);
QilNode val = withParam.Value;
if (IsDebug || !(val is QilIterator || val is QilLiteral))
{
QilIterator let = _f.Let(val);
let.DebugName = _f.QName("with-param " + withParam.Name.QualifiedName, XmlReservedNs.NsXslDebug).ToString();
_varHelper.AddVariable(let);
withParam.Value = let;
}
}
}
// Push new loop frame on the stack
LoopFocus curLoopSaved = _curLoop;
QilIterator it = _f.For(select);
_curLoop.SetFocus(it);
// Compile sort keys and body
_curLoop.Sort(CompileSorts(content, ref curLoopSaved));
result = GenerateApply(_compiler.Root, node);
result = WrapLoopBody(node.ElemNameLi, result, node.EndTagLi);
result = AddCurrentPositionLast(result);
result = _curLoop.ConstructLoop(result);
// Pop loop frame
_curLoop = curLoopSaved;
result = _varHelper.FinishVariables(result, varScope);
return result;
}