private bool IsConstructedExpression(QilNode nd) {
QilTernary ndCond;
// In debug mode, all functions should return void (streamed to writer), so that call stack
// consistently shows caller's line number
if (this.qil.IsDebug)
return true;
if (nd.XmlType.IsNode) {
switch (nd.NodeType) {
case QilNodeType.ElementCtor:
case QilNodeType.AttributeCtor:
case QilNodeType.CommentCtor:
case QilNodeType.PICtor:
case QilNodeType.TextCtor:
case QilNodeType.RawTextCtor:
case QilNodeType.DocumentCtor:
case QilNodeType.NamespaceDecl:
case QilNodeType.XsltCopy:
case QilNodeType.XsltCopyOf:
case QilNodeType.Choice:
return true;
case QilNodeType.Loop:
// Return true if the return expression is constructed
return IsConstructedExpression(((QilLoop) nd).Body);
case QilNodeType.Sequence:
// Return true if the list is empty or at least one expression in the list is constructed
if (nd.Count == 0)
return true;
foreach (QilNode ndItem in nd) {
if (IsConstructedExpression(ndItem))
return true;
}
break;
case QilNodeType.Conditional:
// Return true if either left and right branches of the conditional are constructed
ndCond = (QilTernary) nd;
return IsConstructedExpression(ndCond.Center) || IsConstructedExpression(ndCond.Right);
case QilNodeType.Invoke:
// Return true if the function might return nodes
return !((QilInvoke) nd).Function.XmlType.IsAtomicValue;
}
}
return false;
}