// // 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); }