├── README.md
├── Aq.ExpressionJsonSerializer
├── packages.config
├── Serializer
│ ├── Serialization.Try.cs
│ ├── Serialization.Label.cs
│ ├── Serialization.Switch.cs
│ ├── Serialization.Dynamic.cs
│ ├── Serialization.ListInit.cs
│ ├── Serialization.DebugInfo.cs
│ ├── Serialization.MemberInit.cs
│ ├── Serialization.Default.cs
│ ├── Serialization.RuntimeVariables.cs
│ ├── Serialization.Unary.cs
│ ├── Serialization.Member.cs
│ ├── Serialization.Block.cs
│ ├── Serialization.TypeBinary.cs
│ ├── Serialization.Invocation.cs
│ ├── Serialization.NewArray.cs
│ ├── Serialization.Conditional.cs
│ ├── Serialization.MethodCall.cs
│ ├── Serialization.Index.cs
│ ├── Serialization.New.cs
│ ├── Serialization.Lambda.cs
│ ├── Serialization.Goto.cs
│ ├── Serialization.Binary.cs
│ ├── Serialization.Parameter.cs
│ ├── Serialization.Constant.cs
│ ├── Serialization.Loop.cs
│ └── Serializer.Reflection.cs
├── Deserializer
│ ├── Deserializer.TryExpression.cs
│ ├── Deserializer.LabelExpression.cs
│ ├── Deserializer.DynamicExpression.cs
│ ├── Deserializer.SwitchExpression.cs
│ ├── Deserializer.ListInitExpression.cs
│ ├── Deserializer.DebugInfoExpression.cs
│ ├── Deserializer.MemberInitExpression.cs
│ ├── Deserializer.DefaultExpression.cs
│ ├── Deserializer.RuntimeVariablesExpression.cs
│ ├── Deserializer.MemberExpression.cs
│ ├── Deserializer.BlockExpression.cs
│ ├── Deserializer.ConditionalExpression.cs
│ ├── Deserializer.IndexExpression.cs
│ ├── Deserializer.TypeBinaryExpression.cs
│ ├── Deserializer.NewArrayExpression.cs
│ ├── Deserializer.InvocationExpression.cs
│ ├── Deserializer.MethodCallExpression.cs
│ ├── Deserializer.LoopExpression.cs
│ ├── Deserializer.ConstantExpression.cs
│ ├── Deserializer.NewExpression.cs
│ ├── Deserializer.GotoExpression.cs
│ ├── Deserializer.LambdaExpression.cs
│ ├── Deserializer.ParameterExpression.cs
│ ├── Deserializer.UnaryExpression.cs
│ ├── Deserializer.BinaryExpression.cs
│ └── Deserializer.Reflection.cs
├── ExpressionJsonConverter.cs
├── Properties
│ └── AssemblyInfo.cs
├── Serializer.cs
├── Deserializer.cs
└── Aq.ExpressionJsonSerializer.csproj
├── LICENSE
├── Aq.ExpressionJsonSerializer.sln
├── Aq.ExpressionJsonSerializer.Tests
├── Properties
│ └── AssemblyInfo.cs
├── Aq.ExpressionJsonSerializer.Tests.csproj
└── ExpressionJsonSerializerTest.cs
├── .gitattributes
└── .gitignore
/README.md:
--------------------------------------------------------------------------------
1 | expression-json-serializer
2 | ==========================
3 |
4 | Expression serializer for JSON.NET
5 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Try.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool TryExpression(Expression expr)
9 | {
10 | var expression = expr as TryExpression;
11 | if (expression == null) { return false; }
12 |
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Label.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool LabelExpression(Expression expr)
9 | {
10 | var expression = expr as LabelExpression;
11 | if (expression == null) { return false; }
12 |
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Switch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool SwitchExpression(Expression expr)
9 | {
10 | var expression = expr as SwitchExpression;
11 | if (expression == null) { return false; }
12 |
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Dynamic.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool DynamicExpression(Expression expr)
9 | {
10 | var expression = expr as DynamicExpression;
11 | if (expression == null) { return false; }
12 |
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.ListInit.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool ListInitExpression(Expression expr)
9 | {
10 | var expression = expr as DefaultExpression;
11 | if (expression == null) { return false; }
12 |
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.DebugInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool DebugInfoExpression(Expression expr)
9 | {
10 | var expression = expr as ConditionalExpression;
11 | if (expression == null) { return false; }
12 |
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.MemberInit.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool MemberInitExpression(Expression expr)
9 | {
10 | var expression = expr as MemberInitExpression;
11 | if (expression == null) { return false; }
12 |
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.TryExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private TryExpression TryExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Default.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool DefaultExpression(Expression expr)
9 | {
10 | var expression = expr as DefaultExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "default");
14 |
15 | return true;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.LabelExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private LabelExpression LabelExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.DynamicExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private DynamicExpression DynamicExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.SwitchExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private SwitchExpression SwitchExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.ListInitExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private ListInitExpression ListInitExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.DebugInfoExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private DebugInfoExpression DebugInfoExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.MemberInitExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private MemberInitExpression MemberInitExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | throw new NotImplementedException();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.RuntimeVariables.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool RuntimeVariablesExpression(Expression expr)
9 | {
10 | var expression = expr as RuntimeVariablesExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "runtimeVariables");
14 | this.Prop("variables", this.Enumerable(expression.Variables, this.Expression));
15 |
16 | return true;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Unary.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool UnaryExpression(Expression expr)
9 | {
10 | var expression = expr as UnaryExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "unary");
14 | this.Prop("operand", this.Expression(expression.Operand));
15 | this.Prop("method", this.Method(expression.Method));
16 |
17 | return true;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Member.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool MemberExpression(Expression expr)
9 | {
10 | var expression = expr as MemberExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "member");
14 | this.Prop("expression", this.Expression(expression.Expression));
15 | this.Prop("member", this.Member(expression.Member));
16 |
17 | return true;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Block.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 |
3 | namespace Aq.ExpressionJsonSerializer
4 | {
5 | partial class Serializer
6 | {
7 | private bool BlockExpression(Expression expr)
8 | {
9 | var expression = expr as BlockExpression;
10 | if (expression == null) { return false; }
11 |
12 | this.Prop("typeName", "block");
13 | this.Prop("expressions", this.Enumerable(expression.Expressions, this.Expression));
14 | this.Prop("variables", this.Enumerable(expression.Variables, this.Expression));
15 |
16 | return true;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.TypeBinary.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool TypeBinaryExpression(Expression expr)
9 | {
10 | var expression = expr as TypeBinaryExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "typeBinary");
14 | this.Prop("expression", this.Expression(expression.Expression));
15 | this.Prop("typeOperand", this.Type(expression.TypeOperand));
16 |
17 | return true;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Invocation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool InvocationExpression(Expression expr)
9 | {
10 | var expression = expr as InvocationExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "invocation");
14 | this.Prop("expression", this.Expression(expression.Expression));
15 | this.Prop("arguments", this.Enumerable(expression.Arguments, this.Expression));
16 |
17 | return true;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.NewArray.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool NewArrayExpression(Expression expr)
9 | {
10 | var expression = expr as NewArrayExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "newArray");
14 | this.Prop("elementType", this.Type(expression.Type.GetElementType()));
15 | this.Prop("expressions", this.Enumerable(expression.Expressions, this.Expression));
16 |
17 | return true;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.DefaultExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private DefaultExpression DefaultExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | switch (nodeType) {
14 | case ExpressionType.Default:
15 | return Expr.Default(type);
16 | default:
17 | throw new NotSupportedException();
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Conditional.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 |
3 | namespace Aq.ExpressionJsonSerializer
4 | {
5 | partial class Serializer
6 | {
7 | private bool ConditionalExpression(Expression expr)
8 | {
9 | var expression = expr as ConditionalExpression;
10 | if (expression == null) { return false; }
11 |
12 | this.Prop("typeName", "conditional");
13 | this.Prop("test", this.Expression(expression.Test));
14 | this.Prop("ifTrue", this.Expression(expression.IfTrue));
15 | this.Prop("ifFalse", this.Expression(expression.IfFalse));
16 |
17 | return true;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.MethodCall.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 |
3 | namespace Aq.ExpressionJsonSerializer
4 | {
5 | partial class Serializer
6 | {
7 | private bool MethodCallExpression(Expression expr)
8 | {
9 | var expression = expr as MethodCallExpression;
10 | if (expression == null) { return false; }
11 |
12 | this.Prop("typeName", "methodCall");
13 | this.Prop("object", this.Expression(expression.Object));
14 | this.Prop("method", this.Method(expression.Method));
15 | this.Prop("arguments", this.Enumerable(expression.Arguments, this.Expression));
16 |
17 | return true;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Index.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool IndexExpression(Expression expr)
9 | {
10 | var expression = expr as IndexExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "index");
14 | this.Prop("object", this.Expression(expression.Object));
15 | this.Prop("indexer", this.Property(expression.Indexer));
16 | this.Prop("arguments", this.Enumerable(expression.Arguments, this.Expression));
17 |
18 | return true;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.New.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool NewExpression(Expression expr)
9 | {
10 | var expression = expr as NewExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "new");
14 | this.Prop("constructor", this.Constructor(expression.Constructor));
15 | this.Prop("arguments", this.Enumerable(expression.Arguments, this.Expression));
16 | this.Prop("members", this.Enumerable(expression.Members, this.Member));
17 |
18 | return true;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Lambda.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool LambdaExpression(Expression expr)
9 | {
10 | var expression = expr as LambdaExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "lambda");
14 | this.Prop("name", expression.Name);
15 | this.Prop("parameters", this.Enumerable(expression.Parameters, this.Expression));
16 | this.Prop("body", this.Expression(expression.Body));
17 | this.Prop("tailCall", expression.TailCall);
18 |
19 | return true;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Goto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Aq.ExpressionJsonSerializer
5 | {
6 | partial class Serializer
7 | {
8 | private bool GotoExpression(Expression expr)
9 | {
10 | var expression = expr as GotoExpression;
11 | if (expression == null) { return false; }
12 |
13 | this.Prop("typeName", "goto");
14 | this.Prop("value", this.Expression(expression.Value));
15 | this.Prop("kind", this.Enum(expression.Kind));
16 | this.Prop("targetName", expression.Target.Name ?? "#" + expression.Target.GetHashCode());
17 | this.Prop("targetType", this.Type(expression.Target.Type));
18 |
19 | return true;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Binary.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 |
3 | namespace Aq.ExpressionJsonSerializer
4 | {
5 | partial class Serializer
6 | {
7 | private bool BinaryExpression(Expression expr)
8 | {
9 | var expression = expr as BinaryExpression;
10 | if (expression == null) { return false; }
11 |
12 | this.Prop("typeName", "binary");
13 | this.Prop("left", this.Expression(expression.Left));
14 | this.Prop("right", this.Expression(expression.Right));
15 | this.Prop("method", this.Method(expression.Method));
16 | this.Prop("conversion", this.Expression(expression.Conversion));
17 | this.Prop("liftToNull", expression.IsLiftedToNull);
18 |
19 | return true;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.RuntimeVariablesExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private RuntimeVariablesExpression RuntimeVariablesExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var variables = this.Prop(obj, "variables", this.Enumerable(this.ParameterExpression));
14 |
15 | switch (nodeType) {
16 | case ExpressionType.RuntimeVariables:
17 | return Expr.RuntimeVariables(variables);
18 | default:
19 | throw new NotSupportedException();
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.MemberExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private MemberExpression MemberExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var expression = this.Prop(obj, "expression", this.Expression);
14 | var member = this.Prop(obj, "member", this.Member);
15 |
16 | switch (nodeType) {
17 | case ExpressionType.MemberAccess:
18 | return Expr.MakeMemberAccess(expression, member);
19 | default:
20 | throw new NotSupportedException();
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.BlockExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private BlockExpression BlockExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var expressions = this.Prop(obj, "expressions", this.Enumerable(this.Expression));
14 | var variables = this.Prop(obj, "variables", this.Enumerable(this.ParameterExpression));
15 |
16 | switch (nodeType) {
17 | case ExpressionType.Block:
18 | return Expr.Block(type, variables, expressions);
19 | default:
20 | throw new NotSupportedException();
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.ConditionalExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private ConditionalExpression ConditionalExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var test = this.Prop(obj, "test", this.Expression);
14 | var ifTrue = this.Prop(obj, "ifTrue", this.Expression);
15 | var ifFalse = this.Prop(obj, "ifFalse", this.Expression);
16 |
17 | switch (nodeType) {
18 | case ExpressionType.Conditional:
19 | return Expr.Condition(test, ifTrue, ifFalse, type);
20 | default:
21 | throw new NotSupportedException();
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.IndexExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private IndexExpression IndexExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var expression = this.Prop(obj, "object", this.Expression);
14 | var indexer = this.Prop(obj, "indexer", this.Property);
15 | var arguments = this.Prop(obj, "arguments", this.Enumerable(this.Expression));
16 |
17 | switch (nodeType) {
18 | case ExpressionType.Index:
19 | return Expr.MakeIndex(expression, indexer, arguments);
20 | default:
21 | throw new NotSupportedException();
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.TypeBinaryExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private TypeBinaryExpression TypeBinaryExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var expression = this.Prop(obj, "expression", this.Expression);
14 | var typeOperand = this.Prop(obj, "typeOperand", this.Type);
15 |
16 | switch (nodeType) {
17 | case ExpressionType.TypeIs:
18 | return Expr.TypeIs(expression, typeOperand);
19 | case ExpressionType.TypeEqual:
20 | return Expr.TypeEqual(expression, typeOperand);
21 | default:
22 | throw new NotSupportedException();
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Parameter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq.Expressions;
4 |
5 | namespace Aq.ExpressionJsonSerializer
6 | {
7 | partial class Serializer
8 | {
9 | private readonly Dictionary
10 | _parameterExpressions = new Dictionary();
11 |
12 | private bool ParameterExpression(Expression expr)
13 | {
14 | var expression = expr as ParameterExpression;
15 | if (expression == null) { return false; }
16 |
17 | string name;
18 | if (!this._parameterExpressions.TryGetValue(expression, out name)) {
19 | name = expression.Name ?? "p_" + Guid.NewGuid().ToString("N");
20 | this._parameterExpressions[expression] = name;
21 | }
22 |
23 | this.Prop("typeName", "parameter");
24 | this.Prop("name", name);
25 |
26 | return true;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.NewArrayExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private NewArrayExpression NewArrayExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var elementType = this.Prop(obj, "elementType", this.Type);
14 | var expressions = this.Prop(obj, "expressions", this.Enumerable(this.Expression));
15 |
16 | switch (nodeType) {
17 | case ExpressionType.NewArrayInit:
18 | return Expr.NewArrayInit(elementType, expressions);
19 | case ExpressionType.NewArrayBounds:
20 | return Expr.NewArrayBounds(elementType, expressions);
21 | default:
22 | throw new NotSupportedException();
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.InvocationExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private InvocationExpression InvocationExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var expression = this.Prop(obj, "expression", this.Expression);
14 | var arguments = this.Prop(obj, "arguments", this.Enumerable(this.Expression));
15 |
16 | switch (nodeType) {
17 | case ExpressionType.Invoke:
18 | if (arguments == null) {
19 | return Expr.Invoke(expression);
20 | }
21 | return Expr.Invoke(expression, arguments);
22 | default:
23 | throw new NotSupportedException();
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Constant.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 |
3 | namespace Aq.ExpressionJsonSerializer
4 | {
5 | partial class Serializer
6 | {
7 | private bool ConstantExpression(Expression expr)
8 | {
9 | var expression = expr as ConstantExpression;
10 | if (expression == null) { return false; }
11 |
12 | this.Prop("typeName", "constant");
13 | if (expression.Value == null) {
14 | this.Prop("value", () => this._writer.WriteNull());
15 | }
16 | else {
17 | var value = expression.Value;
18 | var type = value.GetType();
19 | this.Prop("value", () => {
20 | this._writer.WriteStartObject();
21 | this.Prop("type", this.Type(type));
22 | this.Prop("value", this.Serialize(value, type));
23 | this._writer.WriteEndObject();
24 | });
25 | }
26 |
27 | return true;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.MethodCallExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private MethodCallExpression MethodCallExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var instance = this.Prop(obj, "object", this.Expression);
14 | var method = this.Prop(obj, "method", this.Method);
15 | var arguments = this.Prop(obj, "arguments", this.Enumerable(this.Expression));
16 |
17 | switch (nodeType) {
18 | case ExpressionType.ArrayIndex:
19 | return Expr.ArrayIndex(instance, arguments);
20 | case ExpressionType.Call:
21 | return Expr.Call(instance, method, arguments);
22 | default:
23 | throw new NotSupportedException();
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 aquilae
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.LoopExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private LoopExpression LoopExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var body = this.Prop(obj, "body", this.Expression);
14 |
15 | var breakName = this.Prop(obj, "breakLabelName");
16 | var breakType = this.Prop(obj, "breakLabeType", this.Type);
17 |
18 | var continueName = this.Prop(obj, "continueLabelName");
19 | var contiunueType = this.Prop(obj, "continueLabelType", this.Type);
20 |
21 | if (contiunueType != null) {
22 | return Expr.Loop(body, CreateLabelTarget(breakName, breakType), CreateLabelTarget(continueName, contiunueType));
23 | }
24 |
25 | return Expr.Loop(body, CreateLabelTarget(breakName, breakType));
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.ConstantExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private ConstantExpression ConstantExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | object value;
14 |
15 | var valueTok = this.Prop(obj, "value");
16 | if (valueTok == null || valueTok.Type == JTokenType.Null) {
17 | value = null;
18 | }
19 | else {
20 | var valueObj = (JObject) valueTok;
21 | var valueType = this.Prop(valueObj, "type", this.Type);
22 | value = this.Deserialize(this.Prop(valueObj, "value"), valueType);
23 | }
24 |
25 | switch (nodeType) {
26 | case ExpressionType.Constant:
27 | return Expr.Constant(value, type);
28 | default:
29 | throw new NotSupportedException();
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serialization.Loop.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq.Expressions;
4 | using System.Reflection.Emit;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Serializer
9 | {
10 | private bool LoopExpression(Expression expr)
11 | {
12 | var expression = expr as LoopExpression;
13 | if (expression == null) { return false; }
14 |
15 | this.Prop("typeName", "loop");
16 | this.Prop("body", this.Expression(expression.Body));
17 |
18 | if (expression.BreakLabel != null) {
19 | this.Prop("breakLabelName", expression.BreakLabel.Name ?? "#" + expression.BreakLabel.GetHashCode());
20 | this.Prop("breakLabeType", this.Type(expression.BreakLabel.Type));
21 | }
22 |
23 | if (expression.ContinueLabel != null) {
24 | this.Prop("continueLabelName", expression.ContinueLabel.Name ?? "#" + expression.ContinueLabel.GetHashCode());
25 | this.Prop("continueLabelType", this.Type(expression.ContinueLabel.Type));
26 | }
27 |
28 | return true;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/ExpressionJsonConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 | using System.Reflection;
3 | using Newtonsoft.Json;
4 | using Newtonsoft.Json.Linq;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | public class ExpressionJsonConverter : JsonConverter
9 | {
10 | private static readonly System.Type TypeOfExpression = typeof (Expression);
11 |
12 | public ExpressionJsonConverter(Assembly resolvingAssembly)
13 | {
14 | this._assembly = resolvingAssembly;
15 | }
16 |
17 | public override bool CanConvert(System.Type objectType)
18 | {
19 | return objectType == TypeOfExpression
20 | || objectType.IsSubclassOf(TypeOfExpression);
21 | }
22 |
23 | public override void WriteJson(
24 | JsonWriter writer, object value, JsonSerializer serializer)
25 | {
26 | Serializer.Serialize(writer, serializer, (Expression) value);
27 | }
28 |
29 | public override object ReadJson(
30 | JsonReader reader, System.Type objectType,
31 | object existingValue, JsonSerializer serializer)
32 | {
33 | return Deserializer.Deserialize(
34 | this._assembly, JToken.ReadFrom(reader)
35 | );
36 | }
37 |
38 | private readonly Assembly _assembly;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.NewExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private NewExpression NewExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var constructor = this.Prop(obj, "constructor", this.Constructor);
14 | var arguments = this.Prop(obj, "arguments", this.Enumerable(this.Expression));
15 | var members = this.Prop(obj, "members", this.Enumerable(this.Member));
16 |
17 | switch (nodeType) {
18 | case ExpressionType.New:
19 | if (arguments == null) {
20 | if (members == null) {
21 | return Expr.New(constructor);
22 | }
23 | return Expr.New(constructor, new Expression[0], members);
24 | }
25 | if (members == null) {
26 | return Expr.New(constructor, arguments);
27 | }
28 | return Expr.New(constructor, arguments, members);
29 | default:
30 | throw new NotSupportedException();
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.GotoExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private GotoExpression GotoExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var value = this.Expression(this.Prop(obj, "value"));
14 | var kind = this.Enum(this.Prop(obj, "kind"));
15 | var targetType = this.Type(this.Prop(obj, "targetType"));
16 | var targetName = this.Prop(obj, "targetName").Value();
17 |
18 | switch (kind) {
19 | case GotoExpressionKind.Break:
20 | return Expr.Break(CreateLabelTarget(targetName, targetType), value);
21 | case GotoExpressionKind.Continue:
22 | return Expr.Continue(CreateLabelTarget(targetName, targetType));
23 | case GotoExpressionKind.Goto:
24 | return Expr.Goto(CreateLabelTarget(targetName, targetType), value);
25 | case GotoExpressionKind.Return:
26 | return Expr.Return(CreateLabelTarget(targetName, targetType), value);
27 | default:
28 | throw new NotImplementedException();
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aq.ExpressionJsonSerializer", "Aq.ExpressionJsonSerializer\Aq.ExpressionJsonSerializer.csproj", "{F6FD2AAC-7409-48A1-80C5-112CCAF4FA1A}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aq.ExpressionJsonSerializer.Tests", "Aq.ExpressionJsonSerializer.Tests\Aq.ExpressionJsonSerializer.Tests.csproj", "{348525AE-72C1-4250-81D2-79D244856F7C}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {F6FD2AAC-7409-48A1-80C5-112CCAF4FA1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {F6FD2AAC-7409-48A1-80C5-112CCAF4FA1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {F6FD2AAC-7409-48A1-80C5-112CCAF4FA1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {F6FD2AAC-7409-48A1-80C5-112CCAF4FA1A}.Release|Any CPU.Build.0 = Release|Any CPU
18 | {348525AE-72C1-4250-81D2-79D244856F7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {348525AE-72C1-4250-81D2-79D244856F7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {348525AE-72C1-4250-81D2-79D244856F7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {348525AE-72C1-4250-81D2-79D244856F7C}.Release|Any CPU.Build.0 = Release|Any CPU
22 | EndGlobalSection
23 | GlobalSection(SolutionProperties) = preSolution
24 | HideSolutionNode = FALSE
25 | EndGlobalSection
26 | EndGlobal
27 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Aq.ExpressionJsonSerializer")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Aq.ExpressionJsonSerializer")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("da0875e2-9ef3-401f-a179-87e101fa1073")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.LambdaExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private LambdaExpression LambdaExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var body = this.Prop(obj, "body", this.Expression);
14 | var tailCall = this.Prop(obj, "tailCall").Value();
15 | var parameters = this.Prop(obj, "parameters", this.Enumerable(this.ParameterExpression));
16 |
17 | switch (nodeType) {
18 | case ExpressionType.Lambda:
19 | return Expr.Lambda(body, tailCall, parameters);
20 | default:
21 | throw new NotSupportedException();
22 | }
23 | }
24 |
25 | private LambdaExpression LambdaExpression(JToken token)
26 | {
27 | if (token == null || token.Type != JTokenType.Object) {
28 | return null;
29 | }
30 |
31 | var obj = (JObject) token;
32 | var nodeType = this.Prop(obj, "nodeType", this.Enum);
33 | var type = this.Prop(obj, "type", this.Type);
34 | var typeName = this.Prop(obj, "typeName", t => t.Value());
35 |
36 | if (typeName != "lambda") { return null; }
37 |
38 | return this.LambdaExpression(nodeType, type, obj);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Aq.ExpressionJsonSerializer.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Aq.ExpressionJsonSerializer.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("edba1c1d-d374-4947-9224-a07b016026a7")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.ParameterExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq.Expressions;
4 | using Newtonsoft.Json.Linq;
5 | using Expr = System.Linq.Expressions.Expression;
6 |
7 | namespace Aq.ExpressionJsonSerializer
8 | {
9 | partial class Deserializer
10 | {
11 | private readonly Dictionary
12 | _parameterExpressions = new Dictionary();
13 |
14 | private ParameterExpression ParameterExpression(
15 | ExpressionType nodeType, System.Type type, JObject obj)
16 | {
17 | var name = this.Prop(obj, "name", t => t.Value());
18 |
19 | ParameterExpression result;
20 | if (_parameterExpressions.TryGetValue(name, out result)) {
21 | return result;
22 | }
23 |
24 | switch (nodeType) {
25 | case ExpressionType.Parameter:
26 | result = Expr.Parameter(type, name);
27 | break;
28 | default:
29 | throw new NotSupportedException();
30 | }
31 |
32 | _parameterExpressions[name] = result;
33 | return result;
34 | }
35 |
36 | private ParameterExpression ParameterExpression(JToken token)
37 | {
38 | if (token == null || token.Type != JTokenType.Object) {
39 | return null;
40 | }
41 |
42 | var obj = (JObject) token;
43 | var nodeType = this.Prop(obj, "nodeType", this.Enum);
44 | var type = this.Prop(obj, "type", this.Type);
45 | var typeName = this.Prop(obj, "typeName", t => t.Value());
46 |
47 | if (typeName != "parameter") { return null; }
48 |
49 | return this.ParameterExpression(nodeType, type, obj);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.UnaryExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private UnaryExpression UnaryExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var operand = this.Prop(obj, "operand", this.Expression);
14 | var method = this.Prop(obj, "method", this.Method);
15 |
16 | switch (nodeType) {
17 | case ExpressionType.ArrayLength: return Expr.ArrayLength(operand);
18 | case ExpressionType.Convert: return Expr.Convert(operand, type, method);
19 | case ExpressionType.ConvertChecked: return Expr.ConvertChecked(operand, type, method);
20 | case ExpressionType.Decrement: return Expr.Decrement(operand, method);
21 | case ExpressionType.Increment: return Expr.Increment(operand, method);
22 | case ExpressionType.IsFalse: return Expr.IsFalse(operand, method);
23 | case ExpressionType.IsTrue: return Expr.IsTrue(operand, method);
24 | case ExpressionType.Negate: return Expr.Negate(operand, method);
25 | case ExpressionType.NegateChecked: return Expr.NegateChecked(operand, method);
26 | case ExpressionType.Not: return Expr.Not(operand, method);
27 | case ExpressionType.OnesComplement: return Expr.OnesComplement(operand, method);
28 | case ExpressionType.PostDecrementAssign: return Expr.PostDecrementAssign(operand, method);
29 | case ExpressionType.PostIncrementAssign: return Expr.PostIncrementAssign(operand, method);
30 | case ExpressionType.PreDecrementAssign: return Expr.PreDecrementAssign(operand, method);
31 | case ExpressionType.PreIncrementAssign: return Expr.PreIncrementAssign(operand, method);
32 | case ExpressionType.Quote: return Expr.Quote(operand);
33 | case ExpressionType.Throw: return Expr.Throw(operand, type);
34 | case ExpressionType.TypeAs: return Expr.TypeAs(operand, type);
35 | case ExpressionType.UnaryPlus: return Expr.UnaryPlus(operand, method);
36 | case ExpressionType.Unbox: return Expr.Unbox(operand, type);
37 | default: throw new NotSupportedException();
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.DotSettings
2 | packages/*
3 |
4 | ## Ignore Visual Studio temporary files, build results, and
5 | ## files generated by popular Visual Studio add-ons.
6 |
7 | # User-specific files
8 | *.suo
9 | *.user
10 | *.sln.docstates
11 |
12 | # Build results
13 |
14 | [Dd]ebug/
15 | [Rr]elease/
16 | x64/
17 | build/
18 | [Bb]in/
19 | [Oo]bj/
20 |
21 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
22 | !packages/*/build/
23 |
24 | # MSTest test Results
25 | [Tt]est[Rr]esult*/
26 | [Bb]uild[Ll]og.*
27 |
28 | *_i.c
29 | *_p.c
30 | *.ilk
31 | *.meta
32 | *.obj
33 | *.pch
34 | *.pdb
35 | *.pgc
36 | *.pgd
37 | *.rsp
38 | *.sbr
39 | *.tlb
40 | *.tli
41 | *.tlh
42 | *.tmp
43 | *.tmp_proj
44 | *.log
45 | *.vspscc
46 | *.vssscc
47 | .builds
48 | *.pidb
49 | *.log
50 | *.scc
51 |
52 | # Visual C++ cache files
53 | ipch/
54 | *.aps
55 | *.ncb
56 | *.opensdf
57 | *.sdf
58 | *.cachefile
59 |
60 | # Visual Studio profiler
61 | *.psess
62 | *.vsp
63 | *.vspx
64 |
65 | # Guidance Automation Toolkit
66 | *.gpState
67 |
68 | # ReSharper is a .NET coding add-in
69 | _ReSharper*/
70 | *.[Rr]e[Ss]harper
71 |
72 | # TeamCity is a build add-in
73 | _TeamCity*
74 |
75 | # DotCover is a Code Coverage Tool
76 | *.dotCover
77 |
78 | # NCrunch
79 | *.ncrunch*
80 | .*crunch*.local.xml
81 |
82 | # Installshield output folder
83 | [Ee]xpress/
84 |
85 | # DocProject is a documentation generator add-in
86 | DocProject/buildhelp/
87 | DocProject/Help/*.HxT
88 | DocProject/Help/*.HxC
89 | DocProject/Help/*.hhc
90 | DocProject/Help/*.hhk
91 | DocProject/Help/*.hhp
92 | DocProject/Help/Html2
93 | DocProject/Help/html
94 |
95 | # Click-Once directory
96 | publish/
97 |
98 | # Publish Web Output
99 | *.Publish.xml
100 |
101 | # NuGet Packages Directory
102 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
103 | #packages/
104 |
105 | # Windows Azure Build Output
106 | csx
107 | *.build.csdef
108 |
109 | # Windows Store app package directory
110 | AppPackages/
111 |
112 | # Others
113 | sql/
114 | *.Cache
115 | ClientBin/
116 | [Ss]tyle[Cc]op.*
117 | ~$*
118 | *~
119 | *.dbmdl
120 | *.[Pp]ublish.xml
121 | *.pfx
122 | *.publishsettings
123 |
124 | # RIA/Silverlight projects
125 | Generated_Code/
126 |
127 | # Backup & report files from converting an old project file to a newer
128 | # Visual Studio version. Backup files are not needed, because we have git ;-)
129 | _UpgradeReport_Files/
130 | Backup*/
131 | UpgradeLog*.XML
132 | UpgradeLog*.htm
133 |
134 | # SQL Server files
135 | App_Data/*.mdf
136 | App_Data/*.ldf
137 |
138 |
139 | #LightSwitch generated files
140 | GeneratedArtifacts/
141 | _Pvt_Extensions/
142 | ModelManifest.xml
143 |
144 | # =========================
145 | # Windows detritus
146 | # =========================
147 |
148 | # Windows image file caches
149 | Thumbs.db
150 | ehthumbs.db
151 |
152 | # Folder config file
153 | Desktop.ini
154 |
155 | # Recycle Bin used on file shares
156 | $RECYCLE.BIN/
157 |
158 | # Mac desktop service store files
159 | .DS_Store
160 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.BinaryExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using Newtonsoft.Json.Linq;
4 | using Expr = System.Linq.Expressions.Expression;
5 |
6 | namespace Aq.ExpressionJsonSerializer
7 | {
8 | partial class Deserializer
9 | {
10 | private BinaryExpression BinaryExpression(
11 | ExpressionType nodeType, System.Type type, JObject obj)
12 | {
13 | var left = this.Prop(obj, "left", this.Expression);
14 | var right = this.Prop(obj, "right", this.Expression);
15 | var method = this.Prop(obj, "method", this.Method);
16 | var conversion = this.Prop(obj, "conversion", this.LambdaExpression);
17 | var liftToNull = this.Prop(obj, "liftToNull").Value();
18 |
19 | switch (nodeType) {
20 | case ExpressionType.Add: return Expr.Add(left, right, method);
21 | case ExpressionType.AddAssign: return Expr.AddAssign(left, right, method, conversion);
22 | case ExpressionType.AddAssignChecked: return Expr.AddAssignChecked(left, right, method, conversion);
23 | case ExpressionType.AddChecked: return Expr.AddChecked(left, right, method);
24 | case ExpressionType.And: return Expr.And(left, right, method);
25 | case ExpressionType.AndAlso: return Expr.AndAlso(left, right, method);
26 | case ExpressionType.AndAssign: return Expr.AndAssign(left, right, method, conversion);
27 | case ExpressionType.ArrayIndex: return Expr.ArrayIndex(left, right);
28 | case ExpressionType.Assign: return Expr.Assign(left, right);
29 | case ExpressionType.Coalesce: return Expr.Coalesce(left, right, conversion);
30 | case ExpressionType.Divide: return Expr.Divide(left, right, method);
31 | case ExpressionType.DivideAssign: return Expr.DivideAssign(left, right, method, conversion);
32 | case ExpressionType.Equal: return Expr.Equal(left, right, liftToNull, method);
33 | case ExpressionType.ExclusiveOr: return Expr.ExclusiveOr(left, right, method);
34 | case ExpressionType.ExclusiveOrAssign: return Expr.ExclusiveOrAssign(left, right, method, conversion);
35 | case ExpressionType.GreaterThan: return Expr.GreaterThan(left, right, liftToNull, method);
36 | case ExpressionType.GreaterThanOrEqual: return Expr.GreaterThanOrEqual(left, right, liftToNull, method);
37 | case ExpressionType.LeftShift: return Expr.LeftShift(left, right, method);
38 | case ExpressionType.LeftShiftAssign: return Expr.LeftShiftAssign(left, right, method, conversion);
39 | case ExpressionType.LessThan: return Expr.LessThan(left, right, liftToNull, method);
40 | case ExpressionType.LessThanOrEqual: return Expr.LessThanOrEqual(left, right, liftToNull, method);
41 | case ExpressionType.Modulo: return Expr.Modulo(left, right, method);
42 | case ExpressionType.ModuloAssign: return Expr.ModuloAssign(left, right, method, conversion);
43 | case ExpressionType.Multiply: return Expr.Multiply(left, right, method);
44 | case ExpressionType.MultiplyAssign: return Expr.MultiplyAssign(left, right, method, conversion);
45 | case ExpressionType.MultiplyAssignChecked: return Expr.MultiplyAssignChecked(left, right, method, conversion);
46 | case ExpressionType.MultiplyChecked: return Expr.MultiplyChecked(left, right, method);
47 | case ExpressionType.NotEqual: return Expr.NotEqual(left, right, liftToNull, method);
48 | case ExpressionType.Or: return Expr.Or(left, right, method);
49 | case ExpressionType.OrAssign: return Expr.OrAssign(left, right, method, conversion);
50 | case ExpressionType.OrElse: return Expr.OrElse(left, right, method);
51 | case ExpressionType.Power: return Expr.Power(left, right, method);
52 | case ExpressionType.PowerAssign: return Expr.PowerAssign(left, right, method, conversion);
53 | case ExpressionType.RightShift: return Expr.RightShift(left, right, method);
54 | case ExpressionType.RightShiftAssign: return Expr.RightShiftAssign(left, right, method, conversion);
55 | case ExpressionType.Subtract: return Expr.Subtract(left, right, method);
56 | case ExpressionType.SubtractAssign: return Expr.SubtractAssign(left, right, method, conversion);
57 | case ExpressionType.SubtractAssignChecked: return Expr.SubtractAssignChecked(left, right, method, conversion);
58 | case ExpressionType.SubtractChecked: return Expr.SubtractChecked(left, right, method);
59 | default: throw new NotSupportedException();
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer.Tests/Aq.ExpressionJsonSerializer.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {348525AE-72C1-4250-81D2-79D244856F7C}
7 | Library
8 | Properties
9 | Aq.ExpressionJsonSerializer.Tests
10 | Aq.ExpressionJsonSerializer.Tests
11 | v4.5
12 | 512
13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 10.0
15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
17 | False
18 | UnitTest
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 4
28 |
29 |
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 | ..\packages\Newtonsoft.Json.5.0.6\lib\net45\Newtonsoft.Json.dll
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | {F6FD2AAC-7409-48A1-80C5-112CCAF4FA1A}
62 | Aq.ExpressionJsonSerializer
63 |
64 |
65 |
66 |
67 |
68 |
69 | False
70 |
71 |
72 | False
73 |
74 |
75 | False
76 |
77 |
78 | False
79 |
80 |
81 |
82 |
83 |
84 |
85 |
92 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer/Serializer.Reflection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 |
5 | namespace Aq.ExpressionJsonSerializer
6 | {
7 | partial class Serializer
8 | {
9 | private static readonly Dictionary>
10 | TypeCache = new Dictionary>();
11 |
12 | private Action Type(Type type)
13 | {
14 | return () => this.TypeInternal(type);
15 | }
16 |
17 | private void TypeInternal(Type type)
18 | {
19 | if (type == null) {
20 | this._writer.WriteNull();
21 | }
22 | else {
23 | Tuple tuple;
24 | if (!TypeCache.TryGetValue(type, out tuple)) {
25 | var assemblyName = type.Assembly.FullName;
26 | if (type.IsGenericType) {
27 | var def = type.GetGenericTypeDefinition();
28 | tuple = new Tuple(
29 | def.Assembly.FullName, def.FullName,
30 | type.GetGenericArguments()
31 | );
32 | }
33 | else {
34 | tuple = new Tuple(
35 | assemblyName, type.FullName, null);
36 | }
37 | TypeCache[type] = tuple;
38 | }
39 |
40 | this._writer.WriteStartObject();
41 | this.Prop("assemblyName", tuple.Item1);
42 | this.Prop("typeName", tuple.Item2);
43 | this.Prop("genericArguments", this.Enumerable(tuple.Item3, this.Type));
44 | this._writer.WriteEndObject();
45 | }
46 | }
47 |
48 | private Action Constructor(ConstructorInfo constructor)
49 | {
50 | return () => this.ConstructorInternal(constructor);
51 | }
52 |
53 | private void ConstructorInternal(ConstructorInfo constructor)
54 | {
55 | if (constructor == null) {
56 | this._writer.WriteNull();
57 | }
58 | else {
59 | this._writer.WriteStartObject();
60 | this.Prop("type", this.Type(constructor.DeclaringType));
61 | this.Prop("name", constructor.Name);
62 | this.Prop("signature", constructor.ToString());
63 | this._writer.WriteEndObject();
64 | }
65 | }
66 |
67 | private Action Method(MethodInfo method)
68 | {
69 | return () => this.MethodInternal(method);
70 | }
71 |
72 | private void MethodInternal(MethodInfo method)
73 | {
74 | if (method == null) {
75 | this._writer.WriteNull();
76 | }
77 | else {
78 | this._writer.WriteStartObject();
79 | if (method.IsGenericMethod) {
80 | var meth = method.GetGenericMethodDefinition();
81 | var generic = method.GetGenericArguments();
82 |
83 | this.Prop("type", this.Type(meth.DeclaringType));
84 | this.Prop("name", meth.Name);
85 | this.Prop("signature", meth.ToString());
86 | this.Prop("generic", this.Enumerable(generic, this.Type));
87 | }
88 | else {
89 | this.Prop("type", this.Type(method.DeclaringType));
90 | this.Prop("name", method.Name);
91 | this.Prop("signature", method.ToString());
92 | }
93 | this._writer.WriteEndObject();
94 | }
95 | }
96 |
97 | private Action Property(PropertyInfo property)
98 | {
99 | return () => this.PropertyInternal(property);
100 | }
101 |
102 | private void PropertyInternal(PropertyInfo property)
103 | {
104 | if (property == null) {
105 | this._writer.WriteNull();
106 | }
107 | else {
108 | this._writer.WriteStartObject();
109 | this.Prop("type", this.Type(property.DeclaringType));
110 | this.Prop("name", property.Name);
111 | this.Prop("signature", property.ToString());
112 | this._writer.WriteEndObject();
113 | }
114 | }
115 |
116 | private Action Member(MemberInfo member)
117 | {
118 | return () => this.MemberInternal(member);
119 | }
120 |
121 | private void MemberInternal(MemberInfo member)
122 | {
123 | if (member == null) {
124 | this._writer.WriteNull();
125 | }
126 | else {
127 | this._writer.WriteStartObject();
128 | this.Prop("type", this.Type(member.DeclaringType));
129 | this.Prop("memberType", (int) member.MemberType);
130 | this.Prop("name", member.Name);
131 | this.Prop("signature", member.ToString());
132 | this._writer.WriteEndObject();
133 | }
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Serializer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq.Expressions;
4 | using System.Reflection;
5 | using Newtonsoft.Json;
6 |
7 | namespace Aq.ExpressionJsonSerializer
8 | {
9 | internal sealed partial class Serializer
10 | {
11 | public static void Serialize(
12 | JsonWriter writer,
13 | JsonSerializer serializer,
14 | Expression expression)
15 | {
16 | var s = new Serializer(writer, serializer);
17 | s.ExpressionInternal(expression);
18 | }
19 |
20 | private readonly JsonWriter _writer;
21 | private readonly JsonSerializer _serializer;
22 |
23 | private Serializer(JsonWriter writer, JsonSerializer serializer)
24 | {
25 | this._writer = writer;
26 | this._serializer = serializer;
27 | }
28 |
29 | private Action Serialize(object value, System.Type type)
30 | {
31 | return () => this._serializer.Serialize(this._writer, value, type);
32 | }
33 |
34 | private void Prop(string name, bool value)
35 | {
36 | this._writer.WritePropertyName(name);
37 | this._writer.WriteValue(value);
38 | }
39 |
40 | private void Prop(string name, int value)
41 | {
42 | this._writer.WritePropertyName(name);
43 | this._writer.WriteValue(value);
44 | }
45 |
46 | private void Prop(string name, string value)
47 | {
48 | this._writer.WritePropertyName(name);
49 | this._writer.WriteValue(value);
50 | }
51 |
52 | private void Prop(string name, Action valueWriter)
53 | {
54 | this._writer.WritePropertyName(name);
55 | valueWriter();
56 | }
57 |
58 | private Action Enum(TEnum value)
59 | {
60 | return () => this.EnumInternal(value);
61 | }
62 |
63 | private void EnumInternal(TEnum value)
64 | {
65 | this._writer.WriteValue(System.Enum.GetName(typeof(TEnum), value));
66 | }
67 |
68 | private Action Enumerable(IEnumerable items, Func func)
69 | {
70 | return () => this.EnumerableInternal(items, func);
71 | }
72 |
73 | private void EnumerableInternal(IEnumerable items, Func func)
74 | {
75 | if (items == null) {
76 | this._writer.WriteNull();
77 | }
78 | else {
79 | this._writer.WriteStartArray();
80 | foreach (var item in items) {
81 | func(item)();
82 | }
83 | this._writer.WriteEndArray();
84 | }
85 | }
86 |
87 | private Action Expression(Expression expression)
88 | {
89 | return () => this.ExpressionInternal(expression);
90 | }
91 |
92 | private void ExpressionInternal(Expression expression)
93 | {
94 | if (expression == null) {
95 | this._writer.WriteNull();
96 | return;
97 | }
98 |
99 | while (expression.CanReduce) {
100 | expression = expression.Reduce();
101 | }
102 |
103 | this._writer.WriteStartObject();
104 |
105 | this.Prop("nodeType", this.Enum(expression.NodeType));
106 | this.Prop("type", this.Type(expression.Type));
107 |
108 | if (this.BinaryExpression(expression)) { goto end; }
109 | if (this.BlockExpression(expression)) { goto end; }
110 | if (this.ConditionalExpression(expression)) { goto end; }
111 | if (this.ConstantExpression(expression)) { goto end; }
112 | if (this.DebugInfoExpression(expression)) { goto end; }
113 | if (this.DefaultExpression(expression)) { goto end; }
114 | if (this.DynamicExpression(expression)) { goto end; }
115 | if (this.GotoExpression(expression)) { goto end; }
116 | if (this.IndexExpression(expression)) { goto end; }
117 | if (this.InvocationExpression(expression)) { goto end; }
118 | if (this.LabelExpression(expression)) { goto end; }
119 | if (this.LambdaExpression(expression)) { goto end; }
120 | if (this.ListInitExpression(expression)) { goto end; }
121 | if (this.LoopExpression(expression)) { goto end; }
122 | if (this.MemberExpression(expression)) { goto end; }
123 | if (this.MemberInitExpression(expression)) { goto end; }
124 | if (this.MethodCallExpression(expression)) { goto end; }
125 | if (this.NewArrayExpression(expression)) { goto end; }
126 | if (this.NewExpression(expression)) { goto end; }
127 | if (this.ParameterExpression(expression)) { goto end; }
128 | if (this.RuntimeVariablesExpression(expression)) { goto end; }
129 | if (this.SwitchExpression(expression)) { goto end; }
130 | if (this.TryExpression(expression)) { goto end; }
131 | if (this.TypeBinaryExpression(expression)) { goto end; }
132 | if (this.UnaryExpression(expression)) { goto end; }
133 |
134 | throw new NotSupportedException();
135 |
136 | end:
137 | this._writer.WriteEndObject();
138 | }
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Linq.Expressions;
5 | using System.Reflection;
6 | using Newtonsoft.Json.Linq;
7 |
8 | namespace Aq.ExpressionJsonSerializer
9 | {
10 | internal sealed partial class Deserializer
11 | {
12 | public static Expression Deserialize(Assembly assembly, JToken token)
13 | {
14 | var d = new Deserializer(assembly);
15 | return d.Expression(token);
16 | }
17 |
18 | private readonly Dictionary _labelTargets = new Dictionary();
19 | private readonly Assembly _assembly;
20 |
21 | private Deserializer(Assembly assembly)
22 | {
23 | this._assembly = assembly;
24 | }
25 |
26 | private object Deserialize(JToken token, System.Type type)
27 | {
28 | return token.ToObject(type);
29 | }
30 |
31 | private T Prop(JObject obj, string name, Func result = null)
32 | {
33 | var prop = obj.Property(name);
34 |
35 | if (result == null)
36 | result = token => token != null ? token.Value() : default(T);
37 |
38 | return result(prop == null ? null : prop.Value);
39 | }
40 |
41 | private JToken Prop(JObject obj, string name)
42 | {
43 | return obj.Property(name).Value;
44 | }
45 |
46 | private T Enum(JToken token)
47 | {
48 | return (T) System.Enum.Parse(typeof(T), token.Value());
49 | }
50 |
51 | private Func> Enumerable(Func result)
52 | {
53 | return token => {
54 | if (token == null || token.Type != JTokenType.Array) {
55 | return null;
56 | }
57 | var array = (JArray) token;
58 | return array.Select(result);
59 | };
60 | }
61 |
62 | private Expression Expression(JToken token)
63 | {
64 | if (token == null || token.Type != JTokenType.Object) {
65 | return null;
66 | }
67 |
68 | var obj = (JObject) token;
69 | var nodeType = this.Prop(obj, "nodeType", this.Enum);
70 | var type = this.Prop(obj, "type", this.Type);
71 | var typeName = this.Prop(obj, "typeName", t => t.Value());
72 |
73 | switch (typeName) {
74 | case "binary": return this.BinaryExpression(nodeType, type, obj);
75 | case "block": return this.BlockExpression(nodeType, type, obj);
76 | case "conditional": return this.ConditionalExpression(nodeType, type, obj);
77 | case "constant": return this.ConstantExpression(nodeType, type, obj);
78 | case "debugInfo": return this.DebugInfoExpression(nodeType, type, obj);
79 | case "default": return this.DefaultExpression(nodeType, type, obj);
80 | case "dynamic": return this.DynamicExpression(nodeType, type, obj);
81 | case "goto": return this.GotoExpression(nodeType, type, obj);
82 | case "index": return this.IndexExpression(nodeType, type, obj);
83 | case "invocation": return this.InvocationExpression(nodeType, type, obj);
84 | case "label": return this.LabelExpression(nodeType, type, obj);
85 | case "lambda": return this.LambdaExpression(nodeType, type, obj);
86 | case "listInit": return this.ListInitExpression(nodeType, type, obj);
87 | case "loop": return this.LoopExpression(nodeType, type, obj);
88 | case "member": return this.MemberExpression(nodeType, type, obj);
89 | case "memberInit": return this.MemberInitExpression(nodeType, type, obj);
90 | case "methodCall": return this.MethodCallExpression(nodeType, type, obj);
91 | case "newArray": return this.NewArrayExpression(nodeType, type, obj);
92 | case "new": return this.NewExpression(nodeType, type, obj);
93 | case "parameter": return this.ParameterExpression(nodeType, type, obj);
94 | case "runtimeVariables": return this.RuntimeVariablesExpression(nodeType, type, obj);
95 | case "switch": return this.SwitchExpression(nodeType, type, obj);
96 | case "try": return this.TryExpression(nodeType, type, obj);
97 | case "typeBinary": return this.TypeBinaryExpression(nodeType, type, obj);
98 | case "unary": return this.UnaryExpression(nodeType, type, obj);
99 | }
100 | throw new NotSupportedException();
101 | }
102 |
103 | private LabelTarget CreateLabelTarget(string name, Type type) {
104 | if (_labelTargets.ContainsKey(name))
105 | return _labelTargets[name];
106 |
107 | _labelTargets[name] = System.Linq.Expressions.Expression.Label(type, name);
108 |
109 | return _labelTargets[name];
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Aq.ExpressionJsonSerializer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {F6FD2AAC-7409-48A1-80C5-112CCAF4FA1A}
8 | Library
9 | Properties
10 | Aq.ExpressionJsonSerializer
11 | Aq.ExpressionJsonSerializer
12 | v4.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | ..\packages\Newtonsoft.Json.5.0.6\lib\net45\Newtonsoft.Json.dll
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
113 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer.Tests/ExpressionJsonSerializerTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 | using System.Reflection;
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using Newtonsoft.Json;
7 |
8 | namespace Aq.ExpressionJsonSerializer.Tests
9 | {
10 | [TestClass]
11 | public class ExpressionJsonSerializerTest
12 | {
13 | [TestMethod]
14 | public void Assignment()
15 | {
16 | TestExpression((Expression>) (c => c.A + c.B));
17 | }
18 |
19 | [TestMethod]
20 | public void BitwiseAnd()
21 | {
22 | TestExpression((Expression>) (c => c.A & c.B));
23 | }
24 |
25 | [TestMethod]
26 | public void LogicalAnd()
27 | {
28 | TestExpression((Expression>) (c => c.A > 0 && c.B > 0));
29 | }
30 |
31 | [TestMethod]
32 | public void ArrayIndex()
33 | {
34 | TestExpression((Expression>) (c => c.Array[0]));
35 | }
36 |
37 | [TestMethod]
38 | public void ArrayLength()
39 | {
40 | TestExpression((Expression>) (c => c.Array.Length));
41 | }
42 |
43 | [TestMethod]
44 | public void Method()
45 | {
46 | TestExpression((Expression>) (c => c.Method()));
47 | }
48 |
49 | [TestMethod]
50 | public void MethodWithArguments()
51 | {
52 | TestExpression((Expression>) (c => c.Method("B")));
53 | }
54 |
55 | [TestMethod]
56 | public void Coalesce()
57 | {
58 | TestExpression((Expression>) (c => c.C ?? c.A));
59 | }
60 |
61 | [TestMethod]
62 | public void Conditional()
63 | {
64 | TestExpression((Expression>) (c => c.C == null ? c.A : c.B));
65 | }
66 |
67 | [TestMethod]
68 | public void Convert()
69 | {
70 | TestExpression((Expression>) (c => (short) (c.C ?? 0)));
71 | }
72 |
73 | [TestMethod]
74 | public void Decrement()
75 | {
76 | TestExpression((Expression>) (c => c.A - 1));
77 | }
78 |
79 | [TestMethod]
80 | public void DivisionWithCast()
81 | {
82 | TestExpression((Expression>) (c => (float) c.A / c.B));
83 | }
84 |
85 | [TestMethod]
86 | public void Equality()
87 | {
88 | TestExpression((Expression>) (c => c.A == c.B));
89 | }
90 |
91 | [TestMethod]
92 | public void Xor()
93 | {
94 | TestExpression((Expression>) (c => c.A ^ c.B));
95 | }
96 |
97 | [TestMethod]
98 | public void LinqExtensions()
99 | {
100 | TestExpression((Expression>) (c => c.Array.FirstOrDefault()));
101 | }
102 |
103 | [TestMethod]
104 | public void GreaterThan()
105 | {
106 | TestExpression((Expression>) (c => c.A > c.B));
107 | }
108 |
109 | [TestMethod]
110 | public void Increment()
111 | {
112 | TestExpression((Expression>) (c => c.A + 1));
113 | }
114 |
115 | [TestMethod]
116 | public void Indexer()
117 | {
118 | TestExpression((Expression>) (c => c["A"]));
119 | }
120 |
121 | [TestMethod]
122 | public void Invoke()
123 | {
124 | TestExpression((Expression>) (c => c.Func()));
125 | }
126 |
127 | [TestMethod]
128 | public void Constant()
129 | {
130 | TestExpression((Expression>) (c => false));
131 | }
132 |
133 | [TestMethod]
134 | public void Lambda()
135 | {
136 | TestExpression((Expression>) (c => ((Func) (_ => _.A))(c)));
137 | }
138 |
139 | [TestMethod]
140 | public void LeftShift()
141 | {
142 | TestExpression((Expression>) (c => c.A << c.C ?? 0));
143 | }
144 |
145 | [TestMethod]
146 | public void PropertyAccess()
147 | {
148 | TestExpression((Expression>) (c => c.B));
149 | }
150 |
151 | [TestMethod]
152 | public void Negation()
153 | {
154 | TestExpression((Expression>) (c => -c.A));
155 | }
156 |
157 | [TestMethod]
158 | public void New()
159 | {
160 | TestExpression((Expression>) (c => new object()));
161 | }
162 |
163 | [TestMethod]
164 | public void NewWithArguments()
165 | {
166 | TestExpression((Expression>) (c => new String('s', 1)));
167 | }
168 |
169 | [TestMethod]
170 | public void InitArray()
171 | {
172 | TestExpression((Expression>) (c => new[] { 0 }));
173 | }
174 |
175 | [TestMethod]
176 | public void InitEmptyArray()
177 | {
178 | TestExpression((Expression>) (c => new int[3, 2]));
179 | }
180 |
181 | [TestMethod]
182 | public void TypeAs()
183 | {
184 | TestExpression((Expression>) (c => c as object));
185 | }
186 |
187 | [TestMethod]
188 | public void TypeOf()
189 | {
190 | TestExpression((Expression>) (c => typeof (Context) == c.GetType()));
191 | }
192 |
193 | [TestMethod]
194 | public void TypeIs()
195 | {
196 | TestExpression((Expression>) (c => c is object));
197 | }
198 |
199 | [TestMethod]
200 | public void MethodResultCast()
201 | {
202 | TestExpression((Expression>) (c => (int) c.Method3()));
203 | }
204 |
205 | private sealed class Context
206 | {
207 | public int A;
208 | public int B { get; set; }
209 | public int? C;
210 | public int[] Array;
211 | public int this[string key]
212 | {
213 | get
214 | {
215 | switch (key) {
216 | case "A": return this.A;
217 | case "B": return this.B;
218 | case "C": return this.C ?? 0;
219 | default: throw new NotImplementedException();
220 | }
221 | }
222 | }
223 | public Func Func;
224 | public int Method() { return this.A; }
225 | public int Method(string key) { return this[key]; }
226 | public object Method3() { return this.A; }
227 | }
228 |
229 | private static void TestExpression(LambdaExpression source)
230 | {
231 | var random = new Random();
232 | int u;
233 | var context = new Context {
234 | A = random.Next(),
235 | B = random.Next(),
236 | C = (u = random.Next(0, 2)) == 0 ? null : (int?) u,
237 | Array = new[] { random.Next() },
238 | Func = () => u
239 | };
240 |
241 | var settings = new JsonSerializerSettings();
242 | settings.Converters.Add(new ExpressionJsonConverter(
243 | Assembly.GetAssembly(typeof (ExpressionJsonSerializerTest))
244 | ));
245 |
246 | var json = JsonConvert.SerializeObject(source, settings);
247 | var target = JsonConvert.DeserializeObject(json, settings);
248 |
249 | Assert.AreEqual(
250 | ExpressionResult(source, context),
251 | ExpressionResult(target, context)
252 | );
253 | }
254 |
255 | private static string ExpressionResult(LambdaExpression expr, Context context)
256 | {
257 | return JsonConvert.SerializeObject(expr.Compile().DynamicInvoke(context));
258 | }
259 | }
260 | }
261 |
--------------------------------------------------------------------------------
/Aq.ExpressionJsonSerializer/Deserializer/Deserializer.Reflection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using Newtonsoft.Json.Linq;
6 |
7 | namespace Aq.ExpressionJsonSerializer
8 | {
9 | partial class Deserializer
10 | {
11 | private static readonly Dictionary>>
12 | TypeCache = new Dictionary>>();
13 |
14 | private static readonly Dictionary>>
15 | ConstructorCache = new Dictionary>>();
16 |
17 | private Type Type(JToken token)
18 | {
19 | if (token == null || token.Type != JTokenType.Object) {
20 | return null;
21 | }
22 |
23 | var obj = (JObject) token;
24 | var assemblyName = this.Prop(obj, "assemblyName", t => t.Value());
25 | var typeName = this.Prop(obj, "typeName", t => t.Value());
26 | var generic = this.Prop(obj, "genericArguments", this.Enumerable(this.Type));
27 |
28 | Dictionary> assemblies;
29 | if (!TypeCache.TryGetValue(this._assembly, out assemblies)) {
30 | assemblies = new Dictionary>();
31 | TypeCache[this._assembly] = assemblies;
32 | }
33 |
34 | Dictionary types;
35 | if (!assemblies.TryGetValue(assemblyName, out types)) {
36 | types = new Dictionary();
37 | assemblies[assemblyName] = types;
38 | }
39 |
40 | Type type;
41 | if (!types.TryGetValue(typeName, out type)) {
42 | type = this._assembly.GetType(typeName);
43 | if (type == null) {
44 | var assembly = Assembly.Load(new AssemblyName(assemblyName));
45 | type = assembly.GetType(typeName);
46 | }
47 | if (type == null) {
48 | throw new Exception(
49 | "Type could not be found: "
50 | + assemblyName + "." + typeName
51 | );
52 | }
53 | types[typeName] = type;
54 | }
55 |
56 | if (generic != null && type.IsGenericTypeDefinition) {
57 | type = type.MakeGenericType(generic.ToArray());
58 | }
59 |
60 | return type;
61 | }
62 |
63 | private ConstructorInfo Constructor(JToken token)
64 | {
65 | if (token == null || token.Type != JTokenType.Object) {
66 | return null;
67 | }
68 |
69 | var obj = (JObject) token;
70 | var type = this.Prop(obj, "type", this.Type);
71 | var name = this.Prop(obj, "name").Value();
72 | var signature = this.Prop(obj, "signature").Value();
73 |
74 | ConstructorInfo constructor;
75 | Dictionary cache2;
76 | Dictionary> cache1;
77 |
78 | if (!ConstructorCache.TryGetValue(type, out cache1)) {
79 | constructor = this.ConstructorInternal(type, name, signature);
80 |
81 | cache2 = new Dictionary<
82 | string, ConstructorInfo>(1) {
83 | {signature, constructor}
84 | };
85 |
86 | cache1 = new Dictionary<
87 | string, Dictionary<
88 | string, ConstructorInfo>>(1) {
89 | {name, cache2}
90 | };
91 |
92 | ConstructorCache[type] = cache1;
93 | }
94 | else if (!cache1.TryGetValue(name, out cache2)) {
95 | constructor = this.ConstructorInternal(type, name, signature);
96 |
97 | cache2 = new Dictionary<
98 | string, ConstructorInfo>(1) {
99 | {signature, constructor}
100 | };
101 |
102 | cache1[name] = cache2;
103 | }
104 | else if (!cache2.TryGetValue(signature, out constructor)) {
105 | constructor = this.ConstructorInternal(type, name, signature);
106 | cache2[signature] = constructor;
107 | }
108 |
109 | return constructor;
110 | }
111 |
112 | private ConstructorInfo ConstructorInternal(
113 | Type type, string name, string signature)
114 | {
115 | var constructor = type
116 | .GetConstructors(BindingFlags.Public | BindingFlags.Instance)
117 | .FirstOrDefault(c => c.Name == name && c.ToString() == signature);
118 |
119 | if (constructor == null) {
120 | constructor = type
121 | .GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)
122 | .FirstOrDefault(c => c.Name == name && c.ToString() == signature);
123 |
124 | if (constructor == null) {
125 | throw new Exception(
126 | "Constructor for type \""
127 | + type.FullName +
128 | "\" with signature \""
129 | + signature +
130 | "\" could not be found"
131 | );
132 | }
133 | }
134 |
135 | return constructor;
136 | }
137 |
138 | private MethodInfo Method(JToken token)
139 | {
140 | if (token == null || token.Type != JTokenType.Object) {
141 | return null;
142 | }
143 |
144 | var obj = (JObject) token;
145 | var type = this.Prop(obj, "type", this.Type);
146 | var name = this.Prop(obj, "name").Value();
147 | var signature = this.Prop(obj, "signature").Value();
148 | var generic = this.Prop(obj, "generic", this.Enumerable(this.Type));
149 |
150 | var methods = type.GetMethods(
151 | BindingFlags.Public | BindingFlags.NonPublic |
152 | BindingFlags.Instance | BindingFlags.Static
153 | );
154 | var method = methods.First(m => m.Name == name && m.ToString() == signature);
155 |
156 | if (generic != null && method.IsGenericMethodDefinition) {
157 | method = method.MakeGenericMethod(generic.ToArray());
158 | }
159 |
160 | return method;
161 | }
162 |
163 | private PropertyInfo Property(JToken token)
164 | {
165 | if (token == null || token.Type != JTokenType.Object) {
166 | return null;
167 | }
168 |
169 | var obj = (JObject) token;
170 | var type = this.Prop(obj, "type", this.Type);
171 | var name = this.Prop(obj, "name").Value();
172 | var signature = this.Prop(obj, "signature").Value();
173 |
174 | var properties = type.GetProperties(
175 | BindingFlags.Public | BindingFlags.NonPublic |
176 | BindingFlags.Instance | BindingFlags.Static
177 | );
178 | return properties.First(p => p.Name == name && p.ToString() == signature);
179 | }
180 |
181 | private MemberInfo Member(JToken token)
182 | {
183 | if (token == null || token.Type != JTokenType.Object) {
184 | return null;
185 | }
186 |
187 | var obj = (JObject) token;
188 | var type = this.Prop(obj, "type", this.Type);
189 | var name = this.Prop(obj, "name").Value();
190 | var signature = this.Prop(obj, "signature").Value();
191 | var memberType = (MemberTypes) this.Prop(obj, "memberType").Value();
192 |
193 | var members = type.GetMembers(
194 | BindingFlags.Public | BindingFlags.NonPublic |
195 | BindingFlags.Instance | BindingFlags.Static
196 | );
197 | return members.First(p => p.MemberType == memberType
198 | && p.Name == name && p.ToString() == signature);
199 | }
200 | }
201 | }
202 |
--------------------------------------------------------------------------------