Skip to content

Commit bd64422

Browse files
committed
Add ObjectNotationFormatter
1 parent 0683bf0 commit bd64422

5 files changed

Lines changed: 386 additions & 45 deletions

File tree

ExpressionToString.sln

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.Visualizer", "Tests.V
2727
EndProject
2828
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests.DataGenerator", "Tests.DataGenerator\Tests.DataGenerator.csproj", "{68EE3CE3-26F0-4934-AFAC-FC7DDE710EF8}"
2929
EndProject
30+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "_visualizerTests.dotnetcore", "_visualizerTests.dotnetcore\_visualizerTests.dotnetcore.csproj", "{E20FCDF7-3E4B-4D4E-A2E7-1CEB94D379B6}"
31+
EndProject
3032
Global
3133
GlobalSection(SharedMSBuildProjectFiles) = preSolution
3234
Visualizer.Shared\Visualizer.Shared.projitems*{16ca0653-e03a-47df-a5bf-292eef9aa5f0}*SharedItemsImports = 13
@@ -111,6 +113,14 @@ Global
111113
{68EE3CE3-26F0-4934-AFAC-FC7DDE710EF8}.Release|Any CPU.Build.0 = Release|Any CPU
112114
{68EE3CE3-26F0-4934-AFAC-FC7DDE710EF8}.ReleaseCI|Any CPU.ActiveCfg = Release|Any CPU
113115
{68EE3CE3-26F0-4934-AFAC-FC7DDE710EF8}.ReleaseCI2017|Any CPU.ActiveCfg = Release|Any CPU
116+
{E20FCDF7-3E4B-4D4E-A2E7-1CEB94D379B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
117+
{E20FCDF7-3E4B-4D4E-A2E7-1CEB94D379B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
118+
{E20FCDF7-3E4B-4D4E-A2E7-1CEB94D379B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
119+
{E20FCDF7-3E4B-4D4E-A2E7-1CEB94D379B6}.Release|Any CPU.Build.0 = Release|Any CPU
120+
{E20FCDF7-3E4B-4D4E-A2E7-1CEB94D379B6}.ReleaseCI|Any CPU.ActiveCfg = Release|Any CPU
121+
{E20FCDF7-3E4B-4D4E-A2E7-1CEB94D379B6}.ReleaseCI|Any CPU.Build.0 = Release|Any CPU
122+
{E20FCDF7-3E4B-4D4E-A2E7-1CEB94D379B6}.ReleaseCI2017|Any CPU.ActiveCfg = Release|Any CPU
123+
{E20FCDF7-3E4B-4D4E-A2E7-1CEB94D379B6}.ReleaseCI2017|Any CPU.Build.0 = Release|Any CPU
114124
EndGlobalSection
115125
GlobalSection(SolutionProperties) = preSolution
116126
HideSolutionNode = FALSE

Shared/ObjectNotationFormatter.cs

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
using ExpressionToString.Util;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Dynamic;
5+
using System.Linq;
6+
using System.Linq.Expressions;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
using static ExpressionToString.Util.Functions;
10+
using static ExpressionToString.FormatterNames;
11+
using static ExpressionToString.Globals;
12+
using System.Collections;
13+
using System.Reflection;
14+
15+
namespace ExpressionToString {
16+
public class ObjectNotationFormatter : WriterBase {
17+
public ObjectNotationFormatter(object o, string language) : base(o, ResolveLanguage(language)) { }
18+
19+
public ObjectNotationFormatter(object o, string language, out Dictionary<string, (int start, int length)> pathSpans) : base(o, ResolveLanguage(language), out pathSpans) { }
20+
21+
// TODO order of properties
22+
// TODO represent parameters using variables, except for first usage where variable is defined
23+
24+
private void WriteObjectCreation(object o) {
25+
//var newKeyword =
26+
// language == CSharp ? "new " :
27+
// language == VisualBasic ? "New " :
28+
// "";
29+
//var withKeyword = language == VisualBasic ? " With " : "";
30+
//var period = language == VisualBasic ? "." : "";
31+
32+
var type = o.GetType();
33+
var typename = type.FriendlyName(language);
34+
35+
//var values = type.GetProperties()
36+
// .Where(prp => prp.Name != "CanReduce")
37+
// .Select(prp => (name: prp.Name, value: prp.GetValue(o)))
38+
// .WhereT((_,value) => value != null)
39+
// .SelectMany(x => {
40+
// var (name, value) = x;
41+
// switch (value) {
42+
// case IEnumerable enumerable when !(o is string):
43+
// return enumerable.ToObjectList()
44+
// .Select((y, index) => {
45+
// if (language == CSharp) {
46+
// return ($"{name}[{index}]", y);
47+
// } else {
48+
// return ($"{name}({index})", y);
49+
// }
50+
// })
51+
// .WhereT((_, innerValue) => innerValue != null)
52+
// .ToList();
53+
// default:
54+
// values = type.GetProperties()
55+
// .Select(prp => ($"."))
56+
// break;
57+
// }
58+
59+
60+
61+
62+
// var valueType = value.GetType();
63+
// if (valueType != typeof(string) && valueType.InheritsFromOrImplements(IEnumerable)) {
64+
65+
// } else {
66+
67+
// }
68+
// })
69+
70+
//switch (o) {
71+
// case IEnumerable enumerable when !(o is string):
72+
// values = enumerable.ToObjectList()
73+
// .Select((x, index) => ($"[{index}]", x))
74+
// .WhereT((_, value) => value != null)
75+
// .ToList();
76+
// break;
77+
// default:
78+
// values =type.GetProperties()
79+
// .Select(prp => ($"."))
80+
// break;
81+
//}
82+
83+
//if (type != typeof(string) && type.InheritsFromOrImplements<IEnumerable>()) {
84+
// values = (o as IEnumerable).ToObjectList()
85+
// .Select((x, index) => ($"[{index}]", x))
86+
// .Where(x => x.Item2 != null)
87+
// .ToList();
88+
//} else {
89+
// values = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
90+
// .Where(fld => !fld.IsStatic)
91+
// .Select(fld => ($".{fld.Name}", fld.GetValue(o)))
92+
// .Where(x => x.Item2 != null)
93+
// .ToList();
94+
//}
95+
96+
//var values = t.GetProperties()
97+
// .Where(prp => prp.Name != "CanReduce")
98+
// .Select(prp => (prp.Name, prp.GetValue(o)))
99+
// .ToList();
100+
101+
102+
103+
//if (language == CSharp) {
104+
// Write($"new {typename} ");
105+
//} else { // language == VisualBasic
106+
107+
//}
108+
109+
110+
111+
112+
var props = o.GetType().GetProperties().Where(x => x.Name != "CanReduce").ToList();
113+
114+
//Write($"{newKeyword}{typename} {{");
115+
116+
117+
switch (language) {
118+
case CSharp:
119+
Write($"new {o.GetType().FriendlyName(language)}");
120+
if (props.Any()) {
121+
Write("{");
122+
Indent();
123+
WriteEOL();
124+
props.ForEach((p, index) => {
125+
if (index > 0) {
126+
Write(",");
127+
WriteEOL();
128+
}
129+
Write(p.Name);
130+
Write(" = ");
131+
132+
object value = p.GetValue(o);
133+
if (p.PropertyType.InheritsFromOrImplementsAny(PropertyTypes)) {
134+
var arglist = (value as IEnumerable).ToObjectList();
135+
Write("new[] {");
136+
WriteNodes(p.Name, arglist, true);
137+
Write("}");
138+
} else if (p.PropertyType.InheritsFromOrImplementsAny(NodeTypes)) {
139+
140+
} else {
141+
142+
}
143+
});
144+
WriteEOL(true);
145+
Write("}");
146+
} else {
147+
Write("()");
148+
}
149+
break;
150+
case VisualBasic:
151+
Write($"New {o.GetType().FriendlyName(language)} With {{");
152+
Write("}");
153+
break;
154+
default:
155+
Write($"{o.GetType().FriendlyName(language)} {{");
156+
Write("}");
157+
break;
158+
159+
}
160+
}
161+
162+
protected override void WriteBinary(BinaryExpression expr) => throw new NotImplementedException();
163+
protected override void WriteUnary(UnaryExpression expr) => throw new NotImplementedException();
164+
protected override void WriteLambda(LambdaExpression expr) => throw new NotImplementedException();
165+
protected override void WriteParameter(ParameterExpression expr) => throw new NotImplementedException();
166+
protected override void WriteConstant(ConstantExpression expr) => throw new NotImplementedException();
167+
protected override void WriteMemberAccess(MemberExpression expr) => throw new NotImplementedException();
168+
protected override void WriteNew(NewExpression expr) => throw new NotImplementedException();
169+
protected override void WriteCall(MethodCallExpression expr) => throw new NotImplementedException();
170+
protected override void WriteMemberInit(MemberInitExpression expr) => throw new NotImplementedException();
171+
protected override void WriteListInit(ListInitExpression expr) => throw new NotImplementedException();
172+
protected override void WriteNewArray(NewArrayExpression expr) => throw new NotImplementedException();
173+
protected override void WriteConditional(ConditionalExpression expr, object metadata) => throw new NotImplementedException();
174+
protected override void WriteDefault(DefaultExpression expr) => throw new NotImplementedException();
175+
protected override void WriteTypeBinary(TypeBinaryExpression expr) => throw new NotImplementedException();
176+
protected override void WriteInvocation(InvocationExpression expr) => throw new NotImplementedException();
177+
protected override void WriteIndex(IndexExpression expr) => throw new NotImplementedException();
178+
protected override void WriteBlock(BlockExpression expr, object metadata) => throw new NotImplementedException();
179+
protected override void WriteSwitch(SwitchExpression expr) => throw new NotImplementedException();
180+
protected override void WriteTry(TryExpression expr) => throw new NotImplementedException();
181+
protected override void WriteLabel(LabelExpression expr) => throw new NotImplementedException();
182+
protected override void WriteGoto(GotoExpression expr) => throw new NotImplementedException();
183+
protected override void WriteLoop(LoopExpression expr) => throw new NotImplementedException();
184+
protected override void WriteRuntimeVariables(RuntimeVariablesExpression expr) => throw new NotImplementedException();
185+
protected override void WriteDebugInfo(DebugInfoExpression expr) => throw new NotImplementedException();
186+
protected override void WriteElementInit(ElementInit elementInit) => throw new NotImplementedException();
187+
protected override void WriteBinding(MemberBinding binding) => throw new NotImplementedException();
188+
protected override void WriteSwitchCase(SwitchCase switchCase) => throw new NotImplementedException();
189+
protected override void WriteCatchBlock(CatchBlock catchBlock) => throw new NotImplementedException();
190+
protected override void WriteLabelTarget(LabelTarget labelTarget) => throw new NotImplementedException();
191+
protected override void WriteBinaryOperationBinder(BinaryOperationBinder binaryOperationBinder, IList<Expression> args) => throw new NotImplementedException();
192+
protected override void WriteConvertBinder(ConvertBinder convertBinder, IList<Expression> args) => throw new NotImplementedException();
193+
protected override void WriteCreateInstanceBinder(CreateInstanceBinder createInstanceBinder, IList<Expression> args) => throw new NotImplementedException();
194+
protected override void WriteDeleteIndexBinder(DeleteIndexBinder deleteIndexBinder, IList<Expression> args) => throw new NotImplementedException();
195+
protected override void WriteDeleteMemberBinder(DeleteMemberBinder deleteMemberBinder, IList<Expression> args) => throw new NotImplementedException();
196+
protected override void WriteGetIndexBinder(GetIndexBinder getIndexBinder, IList<Expression> args) => throw new NotImplementedException();
197+
protected override void WriteGetMemberBinder(GetMemberBinder getMemberBinder, IList<Expression> args) => throw new NotImplementedException();
198+
protected override void WriteInvokeBinder(InvokeBinder invokeBinder, IList<Expression> args) => throw new NotImplementedException();
199+
protected override void WriteInvokeMemberBinder(InvokeMemberBinder invokeMemberBinder, IList<Expression> args) => throw new NotImplementedException();
200+
protected override void WriteSetIndexBinder(SetIndexBinder setIndexBinder, IList<Expression> args) => throw new NotImplementedException();
201+
protected override void WriteSetMemberBinder(SetMemberBinder setMemberBinder, IList<Expression> args) => throw new NotImplementedException();
202+
protected override void WriteUnaryOperationBinder(UnaryOperationBinder unaryOperationBinder, IList<Expression> args) => throw new NotImplementedException();
203+
protected override void WriteParameterDeclarationImpl(ParameterExpression prm) => throw new NotImplementedException();
204+
}
205+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using ExpressionTreeVisualizer;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Linq;
6+
using System.Runtime.Serialization.Formatters.Binary;
7+
using static System.Linq.Expressions.Expression;
8+
using ExpressionToString.Util;
9+
using System.Reflection;
10+
using System.Collections;
11+
12+
namespace _visualizerTests.dotnetcore {
13+
class Program {
14+
static void Main(string[] args) {
15+
var x = Parameter(typeof(int), "x");
16+
var y = Parameter(typeof(int), "y");
17+
var expr = Multiply(
18+
Add(x, y),
19+
Constant(5)
20+
);
21+
22+
//var data = new VisualizerData(expr);
23+
//Console.WriteLine(CanSerialize(data));
24+
25+
var endnodeData = new EndNodeData {
26+
Closure = null,
27+
Name = null,
28+
Type = "int",
29+
Value = "5"
30+
};
31+
//Console.WriteLine(CanSerialize(endnodeData));
32+
33+
var stream = File.Create(Path.GetTempFileName());
34+
var formatter = new BinaryFormatter();
35+
formatter.Serialize(stream, endnodeData);
36+
37+
//var visualizerHost = new VisualizerDevelopmentHost(expr, typeof(Visualizer), typeof(VisualizerDataObjectSource));
38+
//visualizerHost.ShowVisualizer();
39+
40+
}
41+
42+
static (bool success, string failPath, string errorMessage) CanSerialize(object o, string path = "") {
43+
var formatter = new BinaryFormatter();
44+
using (var stream = File.Create(Path.GetTempFileName())) {
45+
return CanSerialize(o, path, formatter, stream);
46+
}
47+
}
48+
49+
static (bool success, string failPath, string errorMessage) CanSerialize(object o, string path, BinaryFormatter formatter, Stream stream) {
50+
if (o == null) { return (false, path, "Null object"); }
51+
52+
string msg;
53+
var t = o.GetType();
54+
if (t.IsPrimitive || t == typeof(string)) { return (true, path, null); }
55+
try {
56+
formatter.Serialize(stream, o);
57+
return (true, path, null);
58+
} catch (Exception ex) {
59+
msg = ex.Message;
60+
}
61+
62+
List<(string, object)> values;
63+
if (t.IsArray) {
64+
values = (o as IEnumerable).ToObjectList()
65+
.Select((x, index) => ($"[{index}]", x))
66+
.Where(x => x.Item2 != null)
67+
.ToList();
68+
} else {
69+
values = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
70+
.Where(fld => !fld.IsStatic)
71+
.Select(fld => ($".{fld.Name}", fld.GetValue(o)))
72+
.Where(x => x.Item2 != null)
73+
.ToList();
74+
}
75+
76+
foreach (var (name, value) in values) {
77+
var ret = CanSerialize(value, path + name, formatter, stream);
78+
if (!ret.success) { return ret; }
79+
}
80+
return (false, path, msg);
81+
}
82+
}
83+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp2.2</TargetFramework>
6+
<LangVersion>latest</LangVersion>
7+
</PropertyGroup>
8+
9+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
10+
<Prefer32Bit>true</Prefer32Bit>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\ExpressionTreeVisualizer.2019\Visualizer.2019.csproj" />
15+
</ItemGroup>
16+
17+
</Project>

0 commit comments

Comments
 (0)