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

VisitIsType() protected method

Generate code for QilNodeType.IsType.
protected VisitIsType ( QilTargetType ndIsType ) : QilNode
ndIsType System.Xml.Xsl.Qil.QilTargetType
return QilNode
        protected override QilNode VisitIsType(QilTargetType ndIsType) {
            XmlQueryType typDerived, typBase;
            XmlTypeCode codeBase;

            typDerived = ndIsType.Source.XmlType;
            typBase = ndIsType.TargetType;
            Debug.Assert(!typDerived.NeverSubtypeOf(typBase), "Normalizer should have eliminated IsType where source can never be a subtype of destination type.");

            // Special Case: Test whether singleton item is a Node
            if (typDerived.IsSingleton && Ref.Equals(typBase, TypeFactory.Node)) {
                NestedVisitEnsureStack(ndIsType.Source);
                Debug.Assert(this.iterCurr.Storage.ItemStorageType == typeof(XPathItem), "If !IsNode, then storage type should be Item");

                // if (item.IsNode op true) goto LabelBranch;
                this.helper.Call(XmlILMethods.ItemIsNode);
                ZeroCompare(QilNodeType.Ne, true);

                return ndIsType;
            }

            // Special Case: Source value is a singleton Node, and we're testing whether it is an Element, Attribute, PI, etc.
            if (MatchesNodeKinds(ndIsType, typDerived, typBase))
                return ndIsType;

            // Special Case: XmlTypeCode is sufficient to describe destination type
            if (Ref.Equals(typBase, TypeFactory.Double)) codeBase = XmlTypeCode.Double;
            else if (Ref.Equals(typBase, TypeFactory.String)) codeBase = XmlTypeCode.String;
            else if (Ref.Equals(typBase, TypeFactory.Boolean)) codeBase = XmlTypeCode.Boolean;
            else if (Ref.Equals(typBase, TypeFactory.Node)) codeBase = XmlTypeCode.Node;
            else codeBase = XmlTypeCode.None;

            if (codeBase != XmlTypeCode.None) {
                // if (runtime.MatchesXmlType(value, code) op true) goto LabelBranch;
                this.helper.LoadQueryRuntime();
                NestedVisitEnsureStack(ndIsType.Source, typeof(XPathItem), !typDerived.IsSingleton);
                this.helper.LoadInteger((int) codeBase);
                this.helper.Call(typDerived.IsSingleton ? XmlILMethods.ItemMatchesCode : XmlILMethods.SeqMatchesCode);
                ZeroCompare(QilNodeType.Ne, true);

                return ndIsType;
            }

            // if (runtime.MatchesXmlType(value, idxType) op true) goto LabelBranch;
            this.helper.LoadQueryRuntime();
            NestedVisitEnsureStack(ndIsType.Source, typeof(XPathItem), !typDerived.IsSingleton);
            this.helper.LoadInteger(this.helper.StaticData.DeclareXmlType(typBase));
            this.helper.Call(typDerived.IsSingleton ? XmlILMethods.ItemMatchesType : XmlILMethods.SeqMatchesType);
            ZeroCompare(QilNodeType.Ne, true);

            return ndIsType;
        }
XmlILVisitor