System.Xml.Xsl.IlGen.XmlILVisitor.Function C# (CSharp) Method

Function() private method

Generate code for the specified function.
private Function ( QilFunction ndFunc ) : void
ndFunc System.Xml.Xsl.Qil.QilFunction
return void
        private void Function(QilFunction ndFunc) {
            MethodInfo methFunc;
            int paramId;
            IteratorDescriptor iterInfo;
            bool useWriter;

            // Annotate each function parameter with a IteratorDescriptor
            foreach (QilIterator iter in ndFunc.Arguments) {
                Debug.Assert(iter.NodeType == QilNodeType.Parameter);

                // Create an IteratorDescriptor for this parameter
                iterInfo = new IteratorDescriptor(this.helper);

                // Add one to parameter index, as 0th parameter is always "this"
                paramId = XmlILAnnotation.Write(iter).ArgumentPosition + 1;

                // The ParameterInfo for each argument should be set as its location
                iterInfo.Storage = StorageDescriptor.Parameter(paramId, GetItemStorageType(iter), !iter.XmlType.IsSingleton);

                // Associate IteratorDescriptor with Let iterator
                XmlILAnnotation.Write(iter).CachedIteratorDescriptor = iterInfo;
            }

            methFunc = XmlILAnnotation.Write(ndFunc).FunctionBinding;
            useWriter = (XmlILConstructInfo.Read(ndFunc).ConstructMethod == XmlILConstructMethod.Writer);

            // Generate query code from QilExpression tree
            this.helper.MethodBegin(methFunc, ndFunc.SourceLine, useWriter);

            foreach (QilIterator iter in ndFunc.Arguments) {
                // DebugInfo: Sequence point just before generating code for the bound expression
                if (this.qil.IsDebug && iter.SourceLine != null)
                    this.helper.DebugSequencePoint(iter.SourceLine);

                // Calculate default value of this parameter
                if (iter.Binding != null) {
                    Debug.Assert(iter.XmlType == TypeFactory.ItemS, "IlGen currently only supports default values in parameters of type item*.");
                    paramId = (iter.Annotation as XmlILAnnotation).ArgumentPosition + 1;

                    // runtime.MatchesXmlType(param, XmlTypeCode.QName);
                    Label lblLocalComputed = this.helper.DefineLabel();
                    this.helper.LoadQueryRuntime();
                    this.helper.LoadParameter(paramId);
                    this.helper.LoadInteger((int)XmlTypeCode.QName);
                    this.helper.Call(XmlILMethods.SeqMatchesCode);

                    this.helper.Emit(OpCodes.Brfalse, lblLocalComputed);

                    // Compute default value of this parameter
                    StartNestedIterator(iter);
                    NestedVisitEnsureStack(iter.Binding, GetItemStorageType(iter), /*isCached:*/!iter.XmlType.IsSingleton);
                    EndNestedIterator(iter);

                    this.helper.SetParameter(paramId);
                    this.helper.MarkLabel(lblLocalComputed);
                }
            }

            StartNestedIterator(ndFunc);

            // If function did not push results to writer, then function will return value(s) (rather than void)
            if (useWriter)
                NestedVisit(ndFunc.Definition);
            else
                NestedVisitEnsureStack(ndFunc.Definition, GetItemStorageType(ndFunc), !ndFunc.XmlType.IsSingleton);

            EndNestedIterator(ndFunc);

            this.helper.MethodEnd();
        }
XmlILVisitor