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

VisitStrConcat() protected method

Generate code for QilNodeType.StrConcat.
protected VisitStrConcat ( QilStrConcat ndStrConcat ) : QilNode
ndStrConcat QilStrConcat
return QilNode
        protected override QilNode VisitStrConcat(QilStrConcat ndStrConcat) {
            LocalBuilder locStringConcat;
            bool fasterConcat;
            QilNode delimiter;
            QilNode listStrings;
            Debug.Assert(!ndStrConcat.Values.XmlType.IsSingleton, "Optimizer should have folded StrConcat of a singleton value");

            // Get delimiter (assuming it's not the empty string)
            delimiter = ndStrConcat.Delimiter;
            if (delimiter.NodeType == QilNodeType.LiteralString && ((string) (QilLiteral) delimiter).Length == 0) {
                delimiter = null;
            }

            listStrings = ndStrConcat.Values;
            if (listStrings.NodeType == QilNodeType.Sequence && listStrings.Count < 5) {
                // Faster concat possible only if cardinality can be guaranteed at compile-time and there's no delimiter
                fasterConcat = true;
                foreach (QilNode ndStr in listStrings) {
                    if (!ndStr.XmlType.IsSingleton)
                        fasterConcat = false;
                }
            }
            else {
                // If more than 4 strings, array will need to be built
                fasterConcat = false;
            }

            if (fasterConcat) {
                foreach (QilNode ndStr in listStrings)
                    NestedVisitEnsureStack(ndStr);

                this.helper.CallConcatStrings(listStrings.Count);
            }
            else {
                // Create StringConcat helper internal class
                locStringConcat = this.helper.DeclareLocal("$$$strcat", typeof(StringConcat));
                this.helper.Emit(OpCodes.Ldloca, locStringConcat);
                this.helper.Call(XmlILMethods.StrCatClear);

                // Set delimiter, if it's not empty string
                if (delimiter != null) {
                    this.helper.Emit(OpCodes.Ldloca, locStringConcat);
                    NestedVisitEnsureStack(delimiter);
                    this.helper.Call(XmlILMethods.StrCatDelim);
                }

                this.helper.Emit(OpCodes.Ldloca, locStringConcat);

                if (listStrings.NodeType == QilNodeType.Sequence) {
                    foreach (QilNode ndStr in listStrings)
                        GenerateConcat(ndStr, locStringConcat);
                }
                else {
                    GenerateConcat(listStrings, locStringConcat);
                }

                // Push resulting string onto stack
                this.helper.Call(XmlILMethods.StrCatResult);
            }

            this.iterCurr.Storage = StorageDescriptor.Stack(typeof(string), false);

            return ndStrConcat;
        }
XmlILVisitor