private static void ValuesShouldRoundTrip <T>(LiteralFormatter formatter, LiteralParser parser, params T[] values) { foreach (T value in values) { ValueShouldRoundTrip(value, formatter, parser); } }
private static void ValueShouldRoundTrip <T>(T value, LiteralFormatter formatter, LiteralParser parser) { var type = typeof(T); string formatted = formatter.Format(value); object result; string text = Uri.UnescapeDataString(formatted); parser.TryParseLiteral(type, text, out result).Should().BeTrue(); // Since DateTime values get converted into if (typeof(T) != typeof(DateTime)) { result.Should().BeAssignableTo <T>(); } if (type == typeof(byte[])) { result.As <byte[]>().Should().ContainInOrder(value as byte[]); } else if (type == typeof(XElement)) { result.As <XElement>().Should().Be(value as XElement); } else { result.Should().Be(value); } }
public override string ToString() { switch (ValueType) { case StackValueType.Integer: return(LiteralFormatter.FormatInteger((int)Value)); case StackValueType.Float: return(LiteralFormatter.FormatFloat((float)Value)); case StackValueType.String: return(LiteralFormatter.FormatString(Value.ToString())); default: Debug.Assert(false); return(null); } }
private static void ValuesShouldRoundTrip(LiteralFormatter formatter, LiteralParser parser) { // TODO: reduce coverage, this is overkill and mostly testing XmlConvert. ValuesShouldRoundTrip(formatter, parser, true, false); ValuesShouldRoundTrip(formatter, parser, 0, 1, 255); ValuesShouldRoundTrip(formatter, parser, 0, 1, -1, sbyte.MaxValue, sbyte.MinValue); ValuesShouldRoundTrip(formatter, parser, Decimal.MaxValue, Decimal.MinValue, Decimal.One, Decimal.Zero, Decimal.MinValue, Decimal.MaxValue); ValuesShouldRoundTrip(formatter, parser, 0, 1, -0.1, Double.Epsilon, Double.MaxValue, Double.MinValue, Double.NegativeInfinity, Double.PositiveInfinity, Double.NaN, 7E-06, 9e+09, 9E+16); /*last 2 cases are values with no periods in them*/ ValuesShouldRoundTrip(formatter, parser, 0, 1, -0.1, Single.Epsilon, Single.MaxValue, Single.MinValue, Single.NegativeInfinity, Single.PositiveInfinity, Single.NaN, 7E-06f, 9E+09f); /*last 2 cases are values with no periods in them*/ ValuesShouldRoundTrip(formatter, parser, 0, 1, -1, Int16.MaxValue, Int16.MinValue); ValuesShouldRoundTrip(formatter, parser, 0, 1, -1, Int32.MaxValue, Int32.MinValue); ValuesShouldRoundTrip(formatter, parser, 0, 1, -1, Int64.MaxValue, Int64.MinValue); ValuesShouldRoundTrip(formatter, parser, new byte[0], new byte[] { 0 }, new byte[] { 0, 1, byte.MinValue, byte.MaxValue }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); ValuesShouldRoundTrip(formatter, parser, DateTime.MaxValue, DateTime.MinValue, DateTime.Now, DateTime.Today, DateTime.UtcNow); // Kinds? ValuesShouldRoundTrip(formatter, parser, DateTimeOffset.MaxValue, DateTimeOffset.MinValue, DateTimeOffset.Now, DateTimeOffset.UtcNow); ValuesShouldRoundTrip(formatter, parser, TimeSpan.MaxValue, TimeSpan.MinValue, TimeSpan.FromDays(1.5)); ValuesShouldRoundTrip(formatter, parser, Guid.Empty, Guid.NewGuid()); ValuesShouldRoundTrip(formatter, parser, new Binary(new byte[0]), new Binary(new byte[] { 1, 2, byte.MaxValue })); ValuesShouldRoundTrip(formatter, parser, XElement.Parse("<xelement>content<nested><!--comment--></nested> </xelement>")); ValuesShouldRoundTrip(formatter, parser, "", " \t \r\n", ".,();", "\r\n", "\r\n\r\n\r\n\r\n", "\r", "\n", "\n\r", "a\x0302e\x0327\x0627\x0654\x0655", "a surrogate pair: \xd800\xdc00", "left to right \x05d0\x05d1 \x05ea\x05e9 english", "\x1\x2\x3\x4\x5\x20"); }
/// <summary> /// Appends the key using the parentheses-based syntax (e.g. Customers(1)) onto the given <see cref="StringBuilder"/>. /// </summary> /// <param name="builder">The builder to append onto.</param> /// <typeparam name="TProperty">The type used to represent properties.</typeparam> /// <param name="keyProperties">The key properties.</param> /// <param name="getPropertyName">The callback to get each property's name.</param> /// <param name="getPropertyValue">The callback to get each property's value.</param> private static void AppendKeyWithParentheses <TProperty>(StringBuilder builder, ICollection <TProperty> keyProperties, Func <TProperty, string> getPropertyName, Func <TProperty, object> getPropertyValue) { Debug.Assert(builder != null, "builder != null"); Debug.Assert(keyProperties != null, "keyProperties != null"); Debug.Assert(keyProperties.Count != 0, "every resource type must have a key"); Debug.Assert(getPropertyValue != null, "getPropertyValue != null"); LiteralFormatter literalFormatter = LiteralFormatter.ForKeys(false); builder.Append('('); bool first = true; foreach (TProperty property in keyProperties) { if (first) { first = false; } else { builder.Append(','); } if (keyProperties.Count != 1) { builder.Append(getPropertyName(property)); builder.Append('='); } var keyValueText = GetKeyValueAsString(getPropertyValue, property, literalFormatter); builder.Append(keyValueText); } builder.Append(')'); }
/// <summary> /// Gets the value of the key property and serializes it to a string. /// </summary> /// <typeparam name="TProperty">The type used to represent properties.</typeparam> /// <param name="getPropertyValue">The callback to get the value for a property.</param> /// <param name="property">The key property.</param> /// <param name="literalFormatter">The literal formatter to use.</param> /// <returns>The serialized key property value.</returns> private static string GetKeyValueAsString <TProperty>(Func <TProperty, object> getPropertyValue, TProperty property, LiteralFormatter literalFormatter) { Debug.Assert(getPropertyValue != null, "getPropertyValue != null"); object keyValue = getPropertyValue(property); Debug.Assert(keyValue != null, "keyValue != null"); string keyValueText = literalFormatter.Format(keyValue); Debug.Assert(keyValueText != null, "keyValueText != null"); return(keyValueText); }
/// <summary> /// Appends the key for the current resource using segment-based syntax (e.g. Customers/1) onto the given <see cref="StringBuilder"/>. /// </summary> /// <param name="builder">The builder to append onto.</param> /// <typeparam name="TProperty">The type used to represent properties.</typeparam> /// <param name="keyProperties">The key properties.</param> /// <param name="getPropertyValue">The callback to get each property's value.</param> private static void AppendKeyWithSegments <TProperty>(StringBuilder builder, ICollection <TProperty> keyProperties, Func <TProperty, object> getPropertyValue) { Debug.Assert(keyProperties != null, "keyProperties != null"); Debug.Assert(keyProperties.Count == 1, "Only supported for non-composite keys."); builder.Append('/'); builder.Append(GetKeyValueAsString(getPropertyValue, keyProperties.Single(), LiteralFormatter.ForKeys(true))); }
private void ProcessCodePath(TextWriter writer, CodePath path, string indent) { HLInstruction instruction = path.GetFirstInstruction(); while (instruction != null) { Annotate(writer, indent, instruction); if (instruction.UnconditionalBranch) { // Not used } else if (instruction.IsConditionalBranch) { if (_nextIfIsAnElseIf) { writer.Write(string.Format("{0}else if", indent)); _nextIfIsAnElseIf = false; } else { writer.Write(string.Format("{0}if", indent)); } writer.WriteLine(string.Format(" ({0})", instruction.ProcessedStackValue)); writer.WriteLine(indent + "{"); ProcessCodePath(writer, instruction.BranchCodesPaths[instruction.DefaultConditional], indent + " "); writer.WriteLine(indent + "}"); if (instruction.BranchCodesPaths.ContainsKey(!instruction.DefaultConditional)) { CodePath elsePath = instruction.BranchCodesPaths[!instruction.DefaultConditional]; if (elsePath.StartInstruction != null) { if (IsCodePathAnIfPath(elsePath)) { _nextIfIsAnElseIf = true; ProcessCodePath(writer, elsePath, indent); } else { writer.WriteLine(indent + "else"); writer.WriteLine(indent + "{"); ProcessCodePath(writer, elsePath, indent + " "); writer.WriteLine(indent + "}"); } } } } else if (instruction.IsSwitchBranch) { // Do switch cases ever fall through?? I'm assuming they don't here! writer.WriteLine(indent + string.Format("switch ({0})", instruction.ProcessedStackValue)); writer.WriteLine(indent + "{"); // Keep track of code paths are have already outputted to keep // track of offsets that lead to the same codepath var swDonePaths = new List <CodePath>(); foreach (var item in instruction.BranchCodesPaths) { if (swDonePaths.Contains(item.Value)) { continue; } foreach (var item2 in instruction.BranchCodesPaths) { // O(n^2) loop here, there's probably a better way to optimize it if (item2.Value == item.Value) { if (item2.Key.GetType() == typeof(int)) { writer.WriteLine(string.Format("{0} case {1}:", indent, LiteralFormatter.FormatInteger((int)item2.Key))); } else { writer.WriteLine(string.Format("{0} default:", indent)); } } } writer.WriteLine(indent + " {"); ProcessCodePath(writer, item.Value, indent + " "); if (item.Value.EndInstruction == null || !item.Value.EndInstruction.ExitFunction) { writer.WriteLine(indent + " break;"); } writer.WriteLine(indent + " }"); swDonePaths.Add(item.Value); } writer.WriteLine(indent + "}"); } else if (instruction.LoopCodePath != null) { // First of a loop instruction (hopefully, someday, this will be extracted out by the ProgramAnalyzer) // Can we ever break out of a loop? I assume we can't here! while (!instruction.IsConditionalBranch) { instruction = instruction.NextInstruction; Annotate(writer, indent, instruction); } writer.WriteLine(indent + string.Format("while ({0})", instruction.ProcessedStackValue)); writer.WriteLine(indent + "{"); ProcessCodePath(writer, instruction.BranchCodesPaths[true], indent + " "); writer.WriteLine(indent + "}"); } else { WriteInstruction(writer, instruction, indent); } instruction = instruction.NextInstruction; } }