System.Xml.Xsl.IlGen.XmlILVisitor.VisitConditional C# (CSharp) Метод

VisitConditional() защищенный Метод

Generate code for QilNodeType.Conditional.
protected VisitConditional ( QilTernary ndCond ) : QilNode
ndCond System.Xml.Xsl.Qil.QilTernary
Результат QilNode
        protected override QilNode VisitConditional(QilTernary ndCond) {
            XmlILConstructInfo info = XmlILConstructInfo.Read(ndCond);

            if (info.ConstructMethod == XmlILConstructMethod.Writer) {
                Label lblFalse, lblDone;

                // Evaluate if test
                lblFalse = this.helper.DefineLabel();
                NestedVisitWithBranch(ndCond.Left, BranchingContext.OnFalse, lblFalse);

                // Generate true branch code
                NestedVisit(ndCond.Center);

                // Generate false branch code.  If false branch is the empty list,
                if (ndCond.Right.NodeType == QilNodeType.Sequence && ndCond.Right.Count == 0) {
                    // Then generate simplified code that doesn't contain a false branch
                    this.helper.MarkLabel(lblFalse);
                    NestedVisit(ndCond.Right);
                }
                else {
                    // Jump past false branch
                    lblDone = this.helper.DefineLabel();
                    this.helper.EmitUnconditionalBranch(OpCodes.Br, lblDone);

                    // Generate false branch code
                    this.helper.MarkLabel(lblFalse);
                    NestedVisit(ndCond.Right);

                    this.helper.MarkLabel(lblDone);
                }

                this.iterCurr.Storage = StorageDescriptor.None();
            }
            else {
                IteratorDescriptor iterInfoTrue;
                LocalBuilder locBool = null, locCond = null;
                Label lblFalse, lblDone, lblNext;
                Type itemStorageType = GetItemStorageType(ndCond);
                Debug.Assert(info.ConstructMethod == XmlILConstructMethod.Iterator);

                // Evaluate conditional test -- save boolean result in boolResult
                Debug.Assert(ndCond.Left.XmlType.TypeCode == XmlTypeCode.Boolean);
                lblFalse = this.helper.DefineLabel();

                if (ndCond.XmlType.IsSingleton) {
                    // if (!bool-expr) goto LabelFalse;
                    NestedVisitWithBranch(ndCond.Left, BranchingContext.OnFalse, lblFalse);
                }
                else {
                    // CondType itemCond;
                    // int boolResult = bool-expr;
                    locCond = this.helper.DeclareLocal("$$$cond", itemStorageType);
                    locBool = this.helper.DeclareLocal("$$$boolResult", typeof(bool));
                    NestedVisitEnsureLocal(ndCond.Left, locBool);

                    // if (!boolResult) goto LabelFalse;
                    this.helper.Emit(OpCodes.Ldloc, locBool);
                    this.helper.Emit(OpCodes.Brfalse, lblFalse);
                }

                // Generate code for true branch
                ConditionalBranch(ndCond.Center, itemStorageType, locCond);
                iterInfoTrue = this.iterNested;

                // goto LabelDone;
                lblDone = this.helper.DefineLabel();
                this.helper.EmitUnconditionalBranch(OpCodes.Br, lblDone);

                // Generate code for false branch
                // LabelFalse:
                this.helper.MarkLabel(lblFalse);
                ConditionalBranch(ndCond.Right, itemStorageType, locCond);

                // If conditional is not cardinality one, then need to iterate through all values
                if (!ndCond.XmlType.IsSingleton) {
                    Debug.Assert(!ndCond.Center.XmlType.IsSingleton || !ndCond.Right.XmlType.IsSingleton);

                    // IL's rules do not allow OpCodes.Br here
                    // goto LabelDone;
                    this.helper.EmitUnconditionalBranch(OpCodes.Brtrue, lblDone);

                    // LabelNext:
                    lblNext = this.helper.DefineLabel();
                    this.helper.MarkLabel(lblNext);

                    // if (boolResult) goto LabelNextTrue else goto LabelNextFalse;
                    this.helper.Emit(OpCodes.Ldloc, locBool);
                    this.helper.Emit(OpCodes.Brtrue, iterInfoTrue.GetLabelNext());
                    this.helper.EmitUnconditionalBranch(OpCodes.Br, this.iterNested.GetLabelNext());

                    this.iterCurr.SetIterator(lblNext, StorageDescriptor.Local(locCond, itemStorageType, false));
                }

                // LabelDone:
                this.helper.MarkLabel(lblDone);
            }

            return ndCond;
        }
XmlILVisitor