File: System\Xml\Xsl\IlGen\XmlILAnnotation.cs
Web Access
Project: src\src\libraries\System.Private.Xml\src\System.Private.Xml.csproj (System.Private.Xml)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Reflection;
using System.Xml.Xsl.Qil;
 
namespace System.Xml.Xsl.IlGen
{
    /// <summary>
    /// Several annotations are created and attached to Qil nodes during the optimization and code generation phase.
    /// </summary>
    internal sealed class XmlILAnnotation : ListBase<object?>
    {
        private readonly object? _annPrev;
        private MethodInfo? _funcMethod;
        private int _argPos;
        private IteratorDescriptor? _iterInfo;
        private XmlILConstructInfo? _constrInfo;
        private OptimizerPatterns? _optPatt;
 
 
        //-----------------------------------------------
        // Constructor
        //-----------------------------------------------
 
        /// <summary>
        /// Create and initialize XmlILAnnotation for the specified node.
        /// </summary>
        public static XmlILAnnotation Write(QilNode nd)
        {
            XmlILAnnotation? ann = nd.Annotation as XmlILAnnotation;
 
            if (ann == null)
            {
                ann = new XmlILAnnotation(nd.Annotation);
                nd.Annotation = ann;
            }
 
            return ann;
        }
 
        private XmlILAnnotation(object? annPrev)
        {
            _annPrev = annPrev;
        }
 
 
        //-----------------------------------------------
        // Annotations
        //-----------------------------------------------
 
        /// <summary>
        /// User-defined functions and global variables and parameters are bound to Clr MethodInfo objects.
        /// Attached to Function, global Let, and global Parameter nodes.
        /// </summary>
        public MethodInfo? FunctionBinding
        {
            get { return _funcMethod; }
            set { _funcMethod = value; }
        }
 
        /// <summary>
        /// Function arguments are tracked by position.
        /// Attached to function Parameter nodes.
        /// </summary>
        public int ArgumentPosition
        {
            get { return _argPos; }
            set { _argPos = value; }
        }
 
        /// <summary>
        /// The IteratorDescriptor that is derived for Qil For and Let nodes is cached so that it can be used when the
        /// For/Let node is referenced.
        /// Attached to For and Let nodes.
        /// </summary>
        public IteratorDescriptor? CachedIteratorDescriptor
        {
            get { return _iterInfo; }
            set { _iterInfo = value; }
        }
 
        /// <summary>
        /// Contains information about how this expression will be constructed by ILGen.
        /// Attached to any kind of Qil node.
        /// </summary>
        public XmlILConstructInfo? ConstructInfo
        {
            get { return _constrInfo; }
            set { _constrInfo = value; }
        }
 
        /// <summary>
        /// Contains patterns that the subtree rooted at this node matches.
        /// Attached to any kind of Qil node.
        /// </summary>
        public OptimizerPatterns? Patterns
        {
            get { return _optPatt; }
            set { _optPatt = value; }
        }
 
 
        //-----------------------------------------------
        // ListBase implementation
        //-----------------------------------------------
 
        /// <summary>
        /// Return the count of sub-annotations maintained by this annotation.
        /// </summary>
        public override int Count
        {
            get { return (_annPrev != null) ? 3 : 2; }
        }
 
        /// <summary>
        /// Return the annotation at the specified index.
        /// </summary>
        public override object? this[int index]
        {
            get
            {
                if (_annPrev != null)
                {
                    if (index == 0)
                        return _annPrev;
 
                    index--;
                }
 
                return index switch
                {
                    0 => _constrInfo,
                    1 => _optPatt,
 
                    _ => throw new IndexOutOfRangeException(),
                };
            }
            set
            {
                throw new NotSupportedException();
            }
        }
    }
}