diff --git a/README.md b/README.md
index 7d078c9..87aed36 100644
--- a/README.md
+++ b/README.md
@@ -387,7 +387,7 @@ User-defined functions are supplied through an instance of `NameResolver`:
```csharp
var myFunctions = new StaticMemberNameResolver(typeof(MyFunctions));
-var expr = SerilogExpression.Compile("IsHello(User.Name)", nameResolver: customSerilogFunctions);
+var expr = SerilogExpression.Compile("IsHello(User.Name)", nameResolver: myFunctions);
// Filter events based on whether `User.Name` is `'Hello'` :-)
```
diff --git a/appveyor.yml b/appveyor.yml
index b81b089..396eae9 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -8,7 +8,7 @@ artifacts:
deploy:
- provider: NuGet
api_key:
- secure: xIn2Dlahvk1QLaFAazCkjSc83UC1Uv5jeMeyA2NDDiLeHZwFqMm5da6nHEzm6ks5
+ secure: AcMGMnsJdQe1+SQwf+9VpRqcKNw93zr96OlxAEmPob52vqxDNH844SmdYidGX0cL
skip_symbols: true
on:
branch: /^(main|dev)$/
diff --git a/src/Serilog.Expressions/Serilog.Expressions.csproj b/src/Serilog.Expressions/Serilog.Expressions.csproj
index 238042a..545cac6 100644
--- a/src/Serilog.Expressions/Serilog.Expressions.csproj
+++ b/src/Serilog.Expressions/Serilog.Expressions.csproj
@@ -3,7 +3,7 @@
An embeddable mini-language for filtering, enriching, and formatting Serilog
events, ideal for use with JSON or XML configuration.
- 3.4.1
+ 3.5.0
Serilog Contributors
netstandard2.0;netstandard2.1;net5.0
true
@@ -17,7 +17,7 @@
-
+
diff --git a/src/Serilog.Expressions/Templates/Compilation/CompiledRepetition.cs b/src/Serilog.Expressions/Templates/Compilation/CompiledRepetition.cs
index 1049d96..1457032 100644
--- a/src/Serilog.Expressions/Templates/Compilation/CompiledRepetition.cs
+++ b/src/Serilog.Expressions/Templates/Compilation/CompiledRepetition.cs
@@ -22,7 +22,7 @@ class CompiledRepetition : CompiledTemplate
{
readonly Evaluatable _enumerable;
readonly string? _keyOrElementName;
- readonly string? _valueName;
+ readonly string? _valueOrIndexName;
readonly CompiledTemplate _body;
readonly CompiledTemplate? _delimiter;
readonly CompiledTemplate? _alternative;
@@ -30,14 +30,14 @@ class CompiledRepetition : CompiledTemplate
public CompiledRepetition(
Evaluatable enumerable,
string? keyOrElementName,
- string? valueName,
+ string? valueOrIndexName,
CompiledTemplate body,
CompiledTemplate? delimiter,
CompiledTemplate? alternative)
{
_enumerable = enumerable;
_keyOrElementName = keyOrElementName;
- _valueName = valueName;
+ _valueOrIndexName = valueOrIndexName;
_body = body;
_delimiter = delimiter;
_alternative = alternative;
@@ -52,29 +52,32 @@ public override void Evaluate(EvaluationContext ctx, TextWriter output)
return;
}
- if (enumerable is SequenceValue sv)
+ if (enumerable is SequenceValue sequence)
{
- if (sv.Elements.Count == 0)
+ if (sequence.Elements.Count == 0)
{
_alternative?.Evaluate(ctx, output);
return;
}
- var first = true;
- foreach (var element in sv.Elements)
+ for (var i = 0; i < sequence.Elements.Count; ++i)
{
- if (element == null)
- continue; // Should have been invalid but Serilog didn't check and so this does occur in the wild.
+ // Null elements should have been invalid but Serilog didn't check, and so this does occur in the wild.
+ var element = sequence.Elements[i] ?? new ScalarValue(null);
- if (first)
- first = false;
- else
+ if (i != 0)
+ {
_delimiter?.Evaluate(ctx, output);
+ }
var local = _keyOrElementName != null
- ? new(ctx.LogEvent, Locals.Set(ctx.Locals, _keyOrElementName, element))
+ ? new EvaluationContext(ctx.LogEvent, Locals.Set(ctx.Locals, _keyOrElementName, element))
: ctx;
+ local = _valueOrIndexName != null
+ ? new EvaluationContext(local.LogEvent, Locals.Set(local.Locals, _valueOrIndexName, new ScalarValue(i)))
+ : local;
+
_body.Evaluate(local, output);
}
@@ -101,8 +104,8 @@ public override void Evaluate(EvaluationContext ctx, TextWriter output)
? new(ctx.LogEvent, Locals.Set(ctx.Locals, _keyOrElementName, new ScalarValue(member.Name)))
: ctx;
- local = _valueName != null
- ? new(local.LogEvent, Locals.Set(local.Locals, _valueName, member.Value))
+ local = _valueOrIndexName != null
+ ? new(local.LogEvent, Locals.Set(local.Locals, _valueOrIndexName, member.Value))
: local;
_body.Evaluate(local, output);
@@ -129,8 +132,8 @@ public override void Evaluate(EvaluationContext ctx, TextWriter output)
? new(ctx.LogEvent, Locals.Set(ctx.Locals, _keyOrElementName, element.Key))
: ctx;
- local = _valueName != null
- ? new(local.LogEvent, Locals.Set(local.Locals, _valueName, element.Value))
+ local = _valueOrIndexName != null
+ ? new(local.LogEvent, Locals.Set(local.Locals, _valueOrIndexName, element.Value))
: local;
_body.Evaluate(local, output);
diff --git a/src/Serilog.Expressions/Templates/Compilation/NameResolution/TemplateLocalNameResolver.cs b/src/Serilog.Expressions/Templates/Compilation/NameResolution/TemplateLocalNameBinder.cs
similarity index 97%
rename from src/Serilog.Expressions/Templates/Compilation/NameResolution/TemplateLocalNameResolver.cs
rename to src/Serilog.Expressions/Templates/Compilation/NameResolution/TemplateLocalNameBinder.cs
index 60bdb57..cf8683c 100644
--- a/src/Serilog.Expressions/Templates/Compilation/NameResolution/TemplateLocalNameResolver.cs
+++ b/src/Serilog.Expressions/Templates/Compilation/NameResolution/TemplateLocalNameBinder.cs
@@ -76,7 +76,7 @@ Template Transform(Repetition rep, Stack locals)
locals.Pop();
return new Repetition(
- rep.Enumerable,
+ ExpressionLocalNameBinder.BindLocalValueNames(rep.Enumerable, locals),
rep.BindingNames,
body,
rep.Delimiter != null ? Transform(rep.Delimiter, locals) : null,
diff --git a/test/Serilog.Expressions.Tests/Cases/template-evaluation-cases.asv b/test/Serilog.Expressions.Tests/Cases/template-evaluation-cases.asv
index 5df712a..6c30df5 100644
--- a/test/Serilog.Expressions.Tests/Cases/template-evaluation-cases.asv
+++ b/test/Serilog.Expressions.Tests/Cases/template-evaluation-cases.asv
@@ -23,8 +23,10 @@ A{#if false}B{#else if false}C{#else if true}D{#else}E{#end} ⇶ AD
A{#if false}B{#else if true}C{#end} ⇶ AC
{#if true}A{#if false}B{#else}C{#end}D{#end} ⇶ ACD
{#each a in [1,2,3]}<{a}>{#delimit},{#end} ⇶ <1>,<2>,<3>
+{#each a, i in [1,2,3]}<{a}>({i}){#delimit},{#end} ⇶ <1>(0),<2>(1),<3>(2)
{#each a in {x: 1, y: 2}}{a}{#end} ⇶ xy
{#each a, b in {x: 1, y: 2}}{a}.{b}{#end} ⇶ x.1y.2
+{#each a, b in {x: {y: 'z'}}}{#each c, d in b}A: {a}, C: {c}, D: {d}{#end}{#end} ⇶ A: x, C: y, D: z
{#if true}A{#each a in [1]}B{a}{#end}C{#end}D ⇶ AB1CD
{#each a in []}{a}!{#else}none{#end} ⇶ none
Culture-specific {42.34} ⇶ Culture-specific 42,34