public QilNode GenerateInvoke(QilFunction func, IList <XslNode> actualArgs)
{
_iterStack.Clear();
_formalArgs = func.Arguments;
_invokeArgs = _fac.ActualParameterList();
// curArg is an instance variable used in Clone() method
for (_curArg = 0; _curArg < _formalArgs.Count; _curArg++)
{
// Find actual value for a given formal arg
QilParameter formalArg = (QilParameter)_formalArgs[_curArg];
QilNode? invokeArg = FindActualArg(formalArg, actualArgs);
// If actual value was not specified, use the default value and copy its debug comment
if (invokeArg == null)
{
if (_debug)
{
if (formalArg.Name !.NamespaceUri == XmlReservedNs.NsXslDebug)
{
Debug.Assert(formalArg.Name.LocalName == "namespaces", "Cur,Pos,Last don't have default values and should be always added to by caller in AddImplicitArgs()");
Debug.Assert(formalArg.DefaultValue != null, "PrecompileProtoTemplatesHeaders() set it");
invokeArg = Clone(formalArg.DefaultValue);
}
else
{
invokeArg = _fac.DefaultValueMarker();
}
}
else
{
Debug.Assert(formalArg.Name !.NamespaceUri != XmlReservedNs.NsXslDebug, "Cur,Pos,Last don't have default values and should be always added to by caller in AddImplicitArgs(). We don't have $namespaces in !debug.");
invokeArg = Clone(formalArg.DefaultValue !);
}
}
XmlQueryType formalType = formalArg.XmlType !;
XmlQueryType invokeType = invokeArg.XmlType !;
// Possible arg types: anyType, node-set, string, boolean, and number
_fac.CheckXsltType(formalArg);
_fac.CheckXsltType(invokeArg);
if (!invokeType.IsSubtypeOf(formalType))
{
// This may occur only if inferred type of invokeArg is XslFlags.None
Debug.Assert(invokeType == T.ItemS, "Actual argument type is not a subtype of formal argument type");
invokeArg = _fac.TypeAssert(invokeArg, formalType);
}
_invokeArgs.Add(invokeArg);
}