public object Render(ObjectRenderingRequest req) { if (req?.RenderTarget is AnnotatedFormattable) { return(req?.RenderTarget); } var target = req.RenderTarget; var members = target.GetType().GetMembers().Where(m => m.MemberType == MemberTypes.Field || m.MemberType == MemberTypes.Property); var result = new StringBuilder(); result.Append("["); result.Append(ObjectToCode.ToCSharpFriendlyTypeName(target.GetType())); result.Append("]@{"); foreach (var member in members) { result.Append('"'); result.Append(member.Name); result.Append('"'); result.Append('='); var value = Reflection.GetValue(member, target); var req2 = req.NewTarget(value); result.Append(req2.Render()); result.Append(';'); } result.Append("}"); return(new AnnotatedFormattable(result.ToString())); }
public void AnonymousObjectsRenderAsCode() { Assert.Equal(@"new { A = 1, Foo = ""Bar"", }", ObjectToCode.ComplexObjectToPseudoCode(new { A = 1, Foo = "Bar", })); }
public object Render(ObjectRenderingRequest req) { IEnumerable obj = req?.RenderTarget as IEnumerable; if (obj == null) { return(req?.RenderTarget); } var prefix = ""; var result = new StringBuilder(); result.Append("["); result.Append(ObjectToCode.ToCSharpFriendlyTypeName(obj.GetType())); result.Append("]@("); foreach (var rec in obj) { var req2 = req.NewTarget(rec); result.Append(prefix); result.Append(req2.Render()); prefix = ","; } result.Append(")"); return(new AnnotatedFormattable(result.ToString())); }
static string PrettyPrintParameterList(MethodInfo mi) { return("(" + string.Join( ", ", mi.GetParameters().Select( pi => ObjectToCode.GetCSharpFriendlyTypeName(pi.ParameterType) + " " + pi.Name)) + ")"); }
[Test] //Has always been broken public void ConstructedSingleDimOfMultiDimArray() { // ReSharper disable once SuggestUseVarKeywordEvident // ReSharper disable once RedundantArrayCreationExpression object[][,] v = new[] { new object[2, 3] }; Assert.AreEqual("object[][,]", ObjectToCode.GetCSharpFriendlyTypeName(v.GetType())); }
public object Render(ObjectRenderingRequest req) { if (!typeof(Enum).IsAssignableFrom(req.GetType())) { return(req.RenderTarget); } return(new AnnotatedFormattable(req.RenderTarget, "G", "[" + ObjectToCode.ToCSharpFriendlyTypeName(req.RenderTarget.GetType()) + "]", null)); }
public object Render(ObjectRenderingRequest req) { if (!(req?.RenderTarget is Exception)) { return(req?.RenderTarget); } return(new AnnotatedFormattable(req.RenderTarget.ToString(), null, "[" + ObjectToCode.ToCSharpFriendlyTypeName(req.RenderTarget.GetType()) + "]", null)); }
static string PrettyPrintMethod(MethodInfo mi) { var fakeTarget = mi.IsStatic ? "TYPE" : "inst"; return(" " + ObjectToCode.GetCSharpFriendlyTypeName(mi.ReturnType) + " " + fakeTarget + "." + mi.Name + PrettyPrintGenericArguments(mi) + PrettyPrintParameterList(mi)); }
static object PrettyPrintField(FieldInfo fi) { return(" " + (fi.IsLiteral ? "const " : (fi.IsStatic ? "static " : "") + (fi.IsInitOnly ? "readonly " : "")) + ObjectToCode.GetCSharpFriendlyTypeName(fi.FieldType) + " " + fi.Name + (fi.IsLiteral ? " = " + ObjectToCode.ComplexObjectToPseudoCode(fi.GetRawConstantValue()) : "") ); }
static void Simplify(string input) { var newLookup = NodeDeserializer.DeserializeDense(File.ReadAllText(input, Encoding.UTF8)).Simplify(5).UnmarkUnsure(3); Console.WriteLine("Simplified dense representation on next line:"); Console.WriteLine(ObjectToCode.PlainObjectToCode(NodeSerializer.SerializeDense(newLookup))); Console.WriteLine(); Console.WriteLine("Simplified no-statistics dense representation on next line:"); Console.WriteLine(ObjectToCode.PlainObjectToCode(NodeSerializer.SerializeDenseNoStats(newLookup))); }
public void AnonymousObjectsInArray() => Assert.Equal( @"new[] { new { Val = 3, }, new { Val = 42, }, }", ObjectToCode.ComplexObjectToPseudoCode(new[] { new { Val = 3, }, new { Val = 42 } }));
public void InsertsLineBreaksContentsContainLineBreaks() => Assert.Equal( @"{ new { A = 3, B = 'b', }, new { A = 3, B = 'b', }, }".Replace("\r", ""), ObjectToCode.ComplexObjectToPseudoCode(Enumerable.Repeat(new { A = 3, B = 'b' }, 2)));
static string PrettyPrintTypeHeader(Type type) { var prefix = type.IsEnum ? "enum" : type.IsValueType ? "struct" : type.IsInterface ? "interface" : "class"; var baseType = type.BaseType == typeof(object) ? null : type.BaseType; var allInterfaces = type.GetInterfaces(); var interfaces = baseType == null ? allInterfaces : allInterfaces.Except(baseType.GetInterfaces()); var inheritanceTypes = new[] { baseType }.OfType <Type>().Concat(interfaces); var suffix = !inheritanceTypes.Any() || type.IsEnum ? "" : " : " + string.Join(", ", inheritanceTypes.Select(ObjectToCode.GetCSharpFriendlyTypeName)); var name = ObjectToCode.GetCSharpFriendlyTypeName(type); return(prefix + " " + name + suffix); }
static string ComplexObjectToPseudoCode(ExpressionToCodeConfiguration config, object?val, int indent, int valueSize) { var retval = ObjectToCode.PlainObjectToCode(val); if (val is string) { return(ElidePossiblyMultilineString(config, retval ?? throw new InvalidOperationException("retval cannot be null for strings"), indent, valueSize).Trim()); } else if (retval != null) { return(ElideAfter(retval, valueSize)); } else if (val == null) { throw new Exception("Impossible: if val is null, retval cannot be"); } else if (val is Array arrayVal) { return("new[] " + FormatEnumerable(config, arrayVal, indent, valueSize - 6)); } else if (val is IEnumerable enumerableVal) { return(FormatTypeWithListInitializerOrNull(config, val, indent, valueSize, enumerableVal) ?? FormatEnumerable(config, enumerableVal, indent, valueSize)); } else if (val is Expression exprVal) { return(ElideAfter(config.GetExpressionToCode().ToCode(exprVal), valueSize)); } else if (val is IStructuralComparable tuple && val is IComparable && CSharpFriendlyTypeName.IsValueTupleType(val.GetType().GetTypeInfo())) { var collector = new NastyHackyTupleCollector(); tuple.CompareTo(tuple, collector); var sb = new StringBuilder(); sb.Append("("); for (var index = 0; index < collector.CollectedObjects.Count; index++) { var item = collector.CollectedObjects[index]; var asString = ComplexObjectToPseudoCode(config, item, indent + 4, valueSize); if (index > 0) { sb.Append(", "); } sb.Append(asString); } sb.Append(")"); return(ElidePossiblyMultilineString(config, sb.ToString(), indent, valueSize).Trim()); }
public void SupportsBuiltInCases() { Assert.AreEqual("object", ObjectToCode.GetCSharpFriendlyTypeName(typeof(object))); Assert.AreEqual("string", ObjectToCode.GetCSharpFriendlyTypeName(typeof(string))); Assert.AreEqual("char", ObjectToCode.GetCSharpFriendlyTypeName(typeof(char))); Assert.AreEqual("byte", ObjectToCode.GetCSharpFriendlyTypeName(typeof(byte))); Assert.AreEqual("sbyte", ObjectToCode.GetCSharpFriendlyTypeName(typeof(sbyte))); Assert.AreEqual("short", ObjectToCode.GetCSharpFriendlyTypeName(typeof(short))); Assert.AreEqual("ushort", ObjectToCode.GetCSharpFriendlyTypeName(typeof(ushort))); Assert.AreEqual("int", ObjectToCode.GetCSharpFriendlyTypeName(typeof(int))); Assert.AreEqual("uint", ObjectToCode.GetCSharpFriendlyTypeName(typeof(uint))); Assert.AreEqual("long", ObjectToCode.GetCSharpFriendlyTypeName(typeof(long))); Assert.AreEqual("ulong", ObjectToCode.GetCSharpFriendlyTypeName(typeof(ulong))); Assert.AreEqual("void", ObjectToCode.GetCSharpFriendlyTypeName(typeof(void))); }
static string ComplexObjectToPseudoCode(ExpressionToCodeConfiguration config, object val, int indent, int valueSize) { var retval = ObjectToCode.PlainObjectToCode(val); if (val is string) { return(ElidePossiblyMultilineString(config, retval, indent, valueSize).Trim()); } else if (retval != null) { return(ElideAfter(retval, valueSize)); } else if (val is Array) { return("new[] " + FormatEnumerable(config, (IEnumerable)val, indent, valueSize - 6)); } else if (val is IEnumerable) { return(FormatEnumerable(config, (IEnumerable)val, indent, valueSize)); } else if (val is Expression) { return(ElideAfter(config.GetExpressionToCode().ToCode((Expression)val), valueSize)); } else if (val.GetType().GuessTypeClass() == ReflectionHelpers.TypeClass.AnonymousType) { var type = val.GetType(); return("new {" + string.Join( "", type.GetTypeInfo() .GetProperties() .Select( pi => "\n" + new string(' ', indent + 4) + pi.Name + " = " + ComplexObjectToPseudoCode(config, pi.GetValue(val, null), indent + 4, valueSize - pi.Name.Length) + ",") ) + "\n" + new string(' ', indent) + "}"); } else { return(ElideAfter(val.ToString(), valueSize)); } }
static HashAnalysisResult ProcessList <T>(T[] objs) { string name = ObjectToCode.GetCSharpFriendlyTypeName(typeof(T)); if (name.StartsWith("Tuple")) { name = "Tuple"; } else if (name.Contains("AnonymousType")) { name = "Anonymous Type"; } var collisions = AnalyzeHashCollisions(objs); return(new HashAnalysisResult { Name = name, Collisions = collisions, GetHashCodeNS = TimeInNS(() => { foreach (var inst in objs) { inst.GetHashCode(); } }) / objs.Length, EqualsNS = TimeInNS(() => { for (int i = 0; i < objs.Length; i++) { objs[i].Equals(objs[i]); objs[i].Equals(objs[(i + 1) % objs.Length]); } }) / objs.Length / 2, DistinctCountNS = collisions.Rate > 0.99 ? double.NaN : TimeInNS(() => { objs.Distinct().Count(); }) / objs.Length, DictionaryNS = collisions.Rate > 0.99 ? double.NaN : TimeInNS(() => { int idx = 0; objs.ToDictionary(o => o, _ => idx++); }) / objs.Length, }); }
public void IntArray() { Assert.AreEqual("int[]", ObjectToCode.GetCSharpFriendlyTypeName(typeof(int[]))); }
public void ComplexObjectToCodeAlsoSupportsExpressions() => Assert.Equal("() => 42", ObjectToCode.ComplexObjectToPseudoCode((Expression <Func <int> >)(() => 42)));
public void MultiDimArray() { Assert.AreEqual("string[,,]", ObjectToCode.GetCSharpFriendlyTypeName(typeof(string[, , ]))); }
public void GenericList() { Assert.AreEqual("List<DateTime>", ObjectToCode.GetCSharpFriendlyTypeName(typeof(List <DateTime>))); }
static string ComplexObjectToPseudoCode(ExpressionToCodeConfiguration config, object val, int indent, int valueSize) { var retval = ObjectToCode.PlainObjectToCode(val); if (val is string) { return(ElidePossiblyMultilineString(config, retval, indent, valueSize).Trim()); } else if (retval != null) { return(ElideAfter(retval, valueSize)); } else if (val is Array arrayVal) { return("new[] " + FormatEnumerable(config, arrayVal, indent, valueSize - 6)); } else if (val is IEnumerable enumerableVal) { var type = val.GetType(); if (type.GetConstructor(Type.EmptyTypes) is ConstructorInfo ci && ci.IsPublic) { foreach (var pi in type.GetProperties()) { if ( pi.Name == "Item" && pi.CanWrite && pi.GetIndexParameters() is ParameterInfo[] indexPars && indexPars.Length == 1 && typeof(IEnumerable <>).MakeGenericType(typeof(KeyValuePair <,>).MakeGenericType(indexPars[0].ParameterType, pi.PropertyType)) is Type keyEnumerableType && keyEnumerableType.IsAssignableFrom(type) ) { var typeName = type.ToCSharpFriendlyTypeName(); return("new " + typeName + " " + PrintInitializerContents(config, enumerableVal, indexPars[0].ParameterType, pi.PropertyType, indent, valueSize - typeName.Length)); } } } return(FormatEnumerable(config, enumerableVal, indent, valueSize)); } else if (val is Expression exprVal) { return(ElideAfter(config.GetExpressionToCode().ToCode(exprVal), valueSize)); } else if (val is IStructuralComparable tuple && val is IComparable && CSharpFriendlyTypeName.IsValueTupleType(val.GetType().GetTypeInfo())) { var collector = new NastyHackyTupleCollector(); tuple.CompareTo(tuple, collector); var sb = new StringBuilder(); sb.Append("("); for (var index = 0; index < collector.CollectedObjects.Count; index++) { var item = collector.CollectedObjects[index]; var asString = ComplexObjectToPseudoCode(config, item, indent + 4, valueSize); if (index > 0) { sb.Append(", "); } sb.Append(asString); } sb.Append(")"); return(ElidePossiblyMultilineString(config, sb.ToString(), indent, valueSize).Trim()); }
[Test] //Has always been broken public void SingleDimOfMultiDimArray() { Assert.AreEqual("object[][,]", ObjectToCode.GetCSharpFriendlyTypeName(typeof(object[][, ]))); }
public void NestedClasses() { Assert.AreEqual("Outer<string, int>.Nested<DateTime>", ObjectToCode.GetCSharpFriendlyTypeName(typeof(Outer <string, int> .Nested <DateTime>))); }
public void ArrayGenericsMessyMix() { Assert.AreEqual("List<Tuple<int[], string[,]>[][]>[]", ObjectToCode.GetCSharpFriendlyTypeName(typeof(List <Tuple <int[], string[, ]>[][]>[]))); }
public void RussianDolls() { Assert.AreEqual("Tuple<List<int>, Tuple<List<string>>>", ObjectToCode.GetCSharpFriendlyTypeName(typeof(Tuple <List <int>, Tuple <List <string> > >))); }
public void GenericArgumentTypes() { Assert.AreEqual("Func<Z>", ObjectToCode.GetCSharpFriendlyTypeName(typeof(Outer <,> .Nested <>).GetMethod("Method").GetParameters()[0].ParameterType)); }
public void ShortArraysRenderedCompletely() => Assert.Equal("new[] { 1, 2, 3 }", ObjectToCode.ComplexObjectToPseudoCode(new[] { 1, 2, 3 }));
public void LongArraysDoNotBreakAfter30_InCodeGen() => Assert.Equal("new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }", ObjectToCode.ComplexObjectToPseudoCode(Enumerable.Range(1, 32).ToArray()));
public void ShortEnumerablesRenderedCompletely() => Assert.Equal("{ 1, 2, 3 }", ObjectToCode.ComplexObjectToPseudoCode(Enumerable.Range(1, 3)));