예제 #1
0
        //
        // Traverses expressions in "parts" and concats all contiguous literal strings/bytes.
        // Notes:
        //  - We place the string/byte[] values that can be concatenated so far in to "concat" list thats keep track of their total length.
        //    If we reach a non-literal expression and we have some literals ready in "concat" list we perform concat and clear the list.
        //  - "result" contains argument expressions to be passed to a CreateMutableString* overload.
        //  - "opName" contains the name of the operation. This method appends either "non-literal" suffix (for each expression)
        //    or "encoding" suffix (for each concatenated literal).
        //  - "anyBinary" keeps track of whether any iteral visited so far is binary (byte[]).
        //
        private static void ConcatLiteralsAndTransformRecursive(AstGenerator /*!*/ gen, List <Expression> /*!*/ parts,
                                                                LiteralConcatenation /*!*/ concat, MSAst.ExpressionCollectionBuilder /*!*/ result, StringBuilder /*!*/ opName, ref bool anyBinary)
        {
            for (int i = 0; i < parts.Count; i++)
            {
                Expression        part = parts[i];
                StringLiteral     literal;
                StringConstructor ctor;

                if ((literal = part as StringLiteral) != null)
                {
                    concat.Add(literal);
                }
                else if ((ctor = part as StringConstructor) != null)
                {
                    ConcatLiteralsAndTransformRecursive(gen, ctor.Parts, concat, result, opName, ref anyBinary);
                }
                else
                {
                    if (concat.Count > 0)
                    {
                        result.Add(MakeConstant(concat.GetValue()));
                        opName.Append(RubyOps.SuffixLiteral);
                        anyBinary |= concat.IsBinary;
                        concat.Clear();
                    }

                    result.Add(MakeConversion(gen, part));
                    opName.Append(RubyOps.SuffixMutable);
                }
            }
        }
        //
        // Traverses expressions in "parts" and concats all contiguous literal strings/bytes.
        // Notes:
        //  - We place the string/byte[] values that can be concatenated so far in to "concat" list that keeps track of their total length.
        //    If we reach a non-literal expression and we have some literals ready in "concat" list we perform concat and clear the list.
        //  - "result" contains argument expressions to be passed to a CreateMutableString* overload.
        //  - "opName" contains the name of the operation. This method appends either "non-literal" suffix (for each expression)
        //    or "encoding" suffix (for each concatenated literal).
        //
        // Returns false if the parts can't be concatenated due to encoding incompatibilities.
        //
        private static bool ConcatLiteralsAndTransformRecursive(AstGenerator /*!*/ gen, List <Expression> /*!*/ parts,
                                                                LiteralConcatenation /*!*/ concat, MSAst.ExpressionCollectionBuilder /*!*/ result)
        {
            for (int i = 0; i < parts.Count; i++)
            {
                Expression        part = parts[i];
                StringLiteral     literal;
                StringConstructor ctor;

                if ((literal = part as StringLiteral) != null)
                {
                    if (!concat.Add(literal))
                    {
                        return(false);
                    }
                }
                else if ((ctor = part as StringConstructor) != null)
                {
                    if (!ConcatLiteralsAndTransformRecursive(gen, ctor.Parts, concat, result))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (concat.Count > 0)
                    {
                        result.Add(StringLiteral.Transform(concat.GetValue(), concat.Encoding));
                        concat.Clear();
                    }

                    result.Add(MakeConversion(gen, part));
                }
            }

            return(true);
        }