using System; using System.Collections.Generic; using System.Text; namespace Semmle.Extraction { /// /// A trap builder. /// /// A trap builder is used to construct a string that is to be /// persisted in a trap file (similar to how a /// can be used to construct a string). /// public interface ITrapBuilder { /// /// Append the given object to this trap builder. /// ITrapBuilder Append(object arg); /// /// Append the given string to this trap builder. /// ITrapBuilder Append(string arg); /// /// Append a newline to this trap builder. /// ITrapBuilder AppendLine(); } public static class ITrapBuilderExtensions { /// /// Appends a [comma] separated list to a trap builder. /// /// The type of the list. /// The trap builder to append to. /// The separator string (e.g. ",") /// The list of items. /// The original trap builder (fluent interface). public static ITrapBuilder AppendList(this ITrapBuilder tb, string separator, IEnumerable items) { return tb.BuildList(separator, items, (x, tb0) => { tb0.Append(x); }); } /// /// Builds a trap builder using a separator and an action for each item in the list. /// /// The type of the items. /// The trap builder to append to. /// The separator string (e.g. ",") /// The list of items. /// The action on each item. /// The original trap builder (fluent interface). public static ITrapBuilder BuildList(this ITrapBuilder tb, string separator, IEnumerable items, Action action) { bool first = true; foreach (var item in items) { if (first) first = false; else tb.Append(separator); action(item, tb); } return tb; } } /// /// A implementation of , /// used for debugging only. /// public class TrapStringBuilder : ITrapBuilder { readonly StringBuilder StringBuilder = new StringBuilder(); public ITrapBuilder Append(object arg) { StringBuilder.Append(arg); return this; } public ITrapBuilder Append(string arg) { StringBuilder.Append(arg); return this; } public ITrapBuilder AppendLine() { StringBuilder.AppendLine(); return this; } public override string ToString() => StringBuilder.ToString(); } }