Skip to content

Commit 9e8781c

Browse files
committed
Objects and conditionals
1 parent f196d4a commit 9e8781c

19 files changed

+241
-133
lines changed

src/Serilog.Expressions/Expressions/Ast/ArrayExpression.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public ArrayExpression(Expression[] elements)
1414

1515
public override string ToString()
1616
{
17-
return "[" + string.Join(",", Elements.Select(o => o.ToString())) + "]";
17+
return "[" + string.Join(", ", Elements.Select(o => o.ToString())) + "]";
1818
}
1919
}
2020
}

src/Serilog.Expressions/Expressions/Ast/CallExpression.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public override string ToString()
2222
return Operands[0] + "[" + Operands[1] + "]";
2323
}
2424

25-
return OperatorName + "(" + string.Join(",", Operands.Select(o => o.ToString())) + ")";
25+
return OperatorName + "(" + string.Join(", ", Operands.Select(o => o.ToString())) + ")";
2626
}
2727
}
2828
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Serilog.Events;
4+
5+
namespace Serilog.Expressions.Ast
6+
{
7+
class ObjectExpression : Expression
8+
{
9+
public ObjectExpression(KeyValuePair<string, Expression>[] members)
10+
{
11+
Members = members;
12+
}
13+
14+
public KeyValuePair<string, Expression>[] Members { get; }
15+
16+
public override string ToString()
17+
{
18+
return "{" + string.Join(", ", Members.Select(m => $"{new ScalarValue(m.Key)}: {m.Value}")) + "}";
19+
}
20+
}
21+
}

src/Serilog.Expressions/Expressions/Compilation/Linq/Intrinsics.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Linq;
1+
using System.Collections.Generic;
2+
using System.Linq;
23
using System.Text.RegularExpressions;
34
using Serilog.Events;
45
using Serilog.Expressions.Runtime;
@@ -9,14 +10,29 @@ static class Intrinsics
910
{
1011
static readonly LogEventPropertyValue NegativeOne = new ScalarValue(-1);
1112

12-
public static LogEventPropertyValue? ConstructSequenceValue(LogEventPropertyValue[] elements)
13+
public static LogEventPropertyValue? ConstructSequenceValue(LogEventPropertyValue?[] elements)
1314
{
1415
// Avoid upsetting Serilog's (currently) fragile `SequenceValue.Render()`.
1516
if (elements.Any(el => el == null))
1617
return null;
1718
return new SequenceValue(elements);
1819
}
1920

21+
public static LogEventPropertyValue? ConstructStructureValue(string[] names, LogEventPropertyValue?[] values)
22+
{
23+
var properties = new List<LogEventProperty>();
24+
for (var i = 0; i < names.Length; ++i)
25+
{
26+
var value = values[i];
27+
28+
// Avoid upsetting Serilog's `Structure.Render()`.
29+
if (value == null) return null;
30+
31+
properties.Add(new LogEventProperty(names[i], value));
32+
}
33+
return new StructureValue(properties);
34+
}
35+
2036
public static bool CoerceToScalarBoolean(LogEventPropertyValue value)
2137
{
2238
if (value is ScalarValue sv && sv.Value is bool b)

src/Serilog.Expressions/Expressions/Compilation/Linq/LinqExpressionCompiler.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ class LinqExpressionCompiler : SerilogExpressionTransformer<ExpressionBody>
2525
static readonly MethodInfo ConstructSequenceValueMethod = typeof(Intrinsics)
2626
.GetMethod(nameof(Intrinsics.ConstructSequenceValue), BindingFlags.Static | BindingFlags.Public)!;
2727

28+
static readonly MethodInfo ConstructStructureValueMethod = typeof(Intrinsics)
29+
.GetMethod(nameof(Intrinsics.ConstructStructureValue), BindingFlags.Static | BindingFlags.Public)!;
30+
2831
static readonly MethodInfo CoerceToScalarBooleanMethod = typeof(Intrinsics)
2932
.GetMethod(nameof(Intrinsics.CoerceToScalarBoolean), BindingFlags.Static | BindingFlags.Public)!;
3033

@@ -161,6 +164,28 @@ protected override ExpressionBody Transform(ArrayExpression ax)
161164
var arr = LX.NewArrayInit(typeof(LogEventPropertyValue), elements);
162165
return LX.Call(ConstructSequenceValueMethod, arr);
163166
}
167+
168+
protected override ExpressionBody Transform(ObjectExpression ox)
169+
{
170+
var names = new List<string>();
171+
var values = new List<ExpressionBody>();
172+
foreach (var member in ox.Members)
173+
{
174+
if (names.Contains(member.Key))
175+
{
176+
var oldPos = names.IndexOf(member.Key);
177+
values[oldPos] = Transform(member.Value);
178+
}
179+
else
180+
{
181+
names.Add(member.Key);
182+
values.Add(Transform(member.Value));
183+
}
184+
}
185+
var namesConstant = LX.Constant(names.ToArray(), typeof(string[]));
186+
var valuesArr = LX.NewArrayInit(typeof(LogEventPropertyValue), values.ToArray());
187+
return LX.Call(ConstructStructureValueMethod, namesConstant, valuesArr);
188+
}
164189

165190
protected override ExpressionBody Transform(IndexerExpression ix)
166191
{

src/Serilog.Expressions/Expressions/Compilation/Transformations/FilterExpressionTransformer`1.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Serilog.Expressions.Compilation.Transformations
55
{
66
abstract class SerilogExpressionTransformer<TResult>
77
{
8-
protected TResult Transform(Expression expression)
8+
protected virtual TResult Transform(Expression expression)
99
{
1010
return expression switch
1111
{
@@ -17,6 +17,7 @@ protected TResult Transform(Expression expression)
1717
ParameterExpression parameter => Transform(parameter),
1818
IndexerWildcardExpression wildcard => Transform(wildcard),
1919
ArrayExpression array => Transform(array),
20+
ObjectExpression obj => Transform(obj),
2021
IndexerExpression indexer => Transform(indexer),
2122
IndexOfMatchExpression match => Transform(match),
2223
null => throw new ArgumentNullException(nameof(expression)),
@@ -33,6 +34,7 @@ protected TResult Transform(Expression expression)
3334
protected abstract TResult Transform(ParameterExpression prx);
3435
protected abstract TResult Transform(IndexerWildcardExpression wx);
3536
protected abstract TResult Transform(ArrayExpression ax);
37+
protected abstract TResult Transform(ObjectExpression ox);
3638
protected abstract TResult Transform(IndexerExpression ix);
3739
protected abstract TResult Transform(IndexOfMatchExpression mx);
3840
}

src/Serilog.Expressions/Expressions/Compilation/Transformations/IdentityTransformer.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,23 @@ protected override Expression Transform(ArrayExpression ax)
8383
return new ArrayExpression(elements.ToArray());
8484
}
8585

86+
protected override Expression Transform(ObjectExpression ox)
87+
{
88+
var any = false;
89+
var members = new List<KeyValuePair<string, Expression>>();
90+
foreach (var m in ox.Members)
91+
{
92+
if (TryTransform(m.Value, out var result))
93+
any = true;
94+
members.Add(KeyValuePair.Create(m.Key, result));
95+
}
96+
97+
if (!any)
98+
return ox;
99+
100+
return new ObjectExpression(members.ToArray());
101+
}
102+
86103
protected override Expression Transform(IndexerExpression ix)
87104
{
88105
var transformedRecv = TryTransform(ix.Receiver, out var recv);

src/Serilog.Expressions/Expressions/Compilation/Transformations/NodeReplacer.cs

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -19,84 +19,12 @@ public static Expression Replace(Expression expr, Expression source, Expression
1919
_dest = dest;
2020
}
2121

22-
protected override Expression Transform(CallExpression lx)
22+
protected override Expression Transform(Expression x)
2323
{
24-
if (lx == _source)
24+
if (x == _source)
2525
return _dest;
2626

27-
return base.Transform(lx);
28-
}
29-
30-
protected override Expression Transform(ConstantExpression cx)
31-
{
32-
if (cx == _source)
33-
return _dest;
34-
35-
return base.Transform(cx);
36-
}
37-
38-
protected override Expression Transform(AmbientPropertyExpression px)
39-
{
40-
if (px == _source)
41-
return _dest;
42-
43-
return base.Transform(px);
44-
}
45-
46-
protected override Expression Transform(AccessorExpression spx)
47-
{
48-
if (spx == _source)
49-
return _dest;
50-
51-
return base.Transform(spx);
52-
}
53-
54-
protected override Expression Transform(LambdaExpression lmx)
55-
{
56-
if (lmx == _source)
57-
return _dest;
58-
59-
return base.Transform(lmx);
60-
}
61-
62-
protected override Expression Transform(ParameterExpression prx)
63-
{
64-
if (prx == _source)
65-
return _dest;
66-
67-
return base.Transform(prx);
68-
}
69-
70-
protected override Expression Transform(IndexerWildcardExpression wx)
71-
{
72-
if (wx == _source)
73-
return _dest;
74-
75-
return base.Transform(wx);
76-
}
77-
78-
protected override Expression Transform(IndexerExpression ix)
79-
{
80-
if (ix == _source)
81-
return _dest;
82-
83-
return base.Transform(ix);
84-
}
85-
86-
protected override Expression Transform(ArrayExpression ax)
87-
{
88-
if (ax == _source)
89-
return _dest;
90-
91-
return base.Transform(ax);
92-
}
93-
94-
protected override Expression Transform(IndexOfMatchExpression mx)
95-
{
96-
if (mx == _source)
97-
return _dest;
98-
99-
return base.Transform(mx);
27+
return base.Transform(x);
10028
}
10129
}
10230
}

src/Serilog.Expressions/Expressions/Compilation/Wildcards/WildcardSearch.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,10 @@ class WildcardSearch : SerilogExpressionTransformer<IndexerExpression?>
6666
{
6767
return Transform(mx.Corpus);
6868
}
69+
70+
protected override IndexerExpression? Transform(ObjectExpression ox)
71+
{
72+
return null;
73+
}
6974
}
7075
}

src/Serilog.Expressions/Expressions/Operators.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ static class Operators
5757
public const string OpSubstring = "Substring";
5858
public const string OpIndexOfMatch = "IndexOfMatch";
5959
public const string OpIsMatch = "IsMatch";
60+
public const string RuntimeOpIfThenElse = "_Internal_IfThenElse";
6061

6162
public static readonly HashSet<string> WildcardComparators = new HashSet<string>(OperatorComparer)
6263
{

0 commit comments

Comments
 (0)