Skip to content
This repository was archived by the owner on Feb 27, 2022. It is now read-only.

Commit a3a134f

Browse files
authored
Merge pull request #23 from nblumhardt/superpower-v2
Superpower v2
2 parents 68a0b8d + 8b9ded8 commit a3a134f

File tree

11 files changed

+59
-59
lines changed

11 files changed

+59
-59
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*.user
77
*.userosscache
88
*.sln.docstates
9+
.idea
910

1011
# User-specific files (MonoDevelop/Xamarin Studio)
1112
*.userprefs

src/Serilog.Filters.Expressions/Filters/Expressions/FilterExpressionLanguage.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Serilog.Events;
2-
using Serilog.Filters.Expressions.Ast;
32
using Serilog.Filters.Expressions.Compilation;
43
using System;
54
using System.Linq;
@@ -19,9 +18,7 @@ public static class FilterLanguage
1918
/// <returns>A function that evaluates the expression in the context of the log event.</returns>
2019
public static Func<LogEvent, object> CreateFilter(string expression)
2120
{
22-
Func<LogEvent, object> filter;
23-
string error;
24-
if (!TryCreateFilter(expression, out filter, out error))
21+
if (!TryCreateFilter(expression, out var filter, out var error))
2522
throw new ArgumentException(error);
2623

2724
return filter;
@@ -36,8 +33,7 @@ public static Func<LogEvent, object> CreateFilter(string expression)
3633
/// <returns>True if the filter could be created; otherwise, false.</returns>
3734
public static bool TryCreateFilter(string expression, out Func<LogEvent, object> filter, out string error)
3835
{
39-
FilterExpression root;
40-
if (!FilterExpressionParser.TryParse(expression, out root, out error))
36+
if (!FilterExpressionParser.TryParse(expression, out var root, out error))
4137
{
4238
filter = null;
4339
return false;
@@ -54,6 +50,7 @@ public static bool TryCreateFilter(string expression, out Func<LogEvent, object>
5450
/// <param name="text">The text to escape.</param>
5551
/// <returns>The text with any special values escaped. Will need to be passed through
5652
/// <see cref="EscapeStringContent(string)"/> if it is being embedded directly into a filter expression.</returns>
53+
// ReSharper disable once UnusedMember.Global
5754
public static string EscapeLikeExpressionContent(string text)
5855
{
5956
if (text == null) throw new ArgumentNullException(nameof(text));

src/Serilog.Filters.Expressions/Filters/Expressions/Parsing/FilterExpressionParser.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
using System;
22
using Serilog.Filters.Expressions.Ast;
3-
using Superpower;
43

54
namespace Serilog.Filters.Expressions.Parsing
65
{
76
static class FilterExpressionParser
87
{
98
public static FilterExpression Parse(string filterExpression)
109
{
11-
FilterExpression root;
12-
string error;
13-
if (!TryParse(filterExpression, out root, out error))
10+
if (!TryParse(filterExpression, out var root, out var error))
1411
throw new ArgumentException(error);
1512

1613
return root;
@@ -20,17 +17,15 @@ public static bool TryParse(string filterExpression, out FilterExpression root,
2017
{
2118
if (filterExpression == null) throw new ArgumentNullException(nameof(filterExpression));
2219

23-
var tokenizer = new FilterExpressionTokenizer();
24-
var tokenList = tokenizer.TryTokenize(filterExpression);
25-
20+
var tokenList = FilterExpressionTokenizer.Instance.TryTokenize(filterExpression);
2621
if (!tokenList.HasValue)
2722
{
2823
error = tokenList.ToString();
2924
root = null;
3025
return false;
3126
}
3227

33-
var result = FilterExpressionTokenParsers.Expr.AtEnd().TryParse(tokenList.Value);
28+
var result = FilterExpressionTokenParsers.TryParse(tokenList.Value);
3429
if (!result.HasValue)
3530
{
3631
error = result.ToString();

src/Serilog.Filters.Expressions/Filters/Expressions/Parsing/FilterExpressionTokenParsers.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@
44
using System;
55
using System.Globalization;
66
using System.Linq;
7+
using Superpower.Model;
78

89
namespace Serilog.Filters.Expressions.Parsing
910
{
1011
static class FilterExpressionTokenParsers
1112
{
13+
public static TokenListParserResult<FilterExpressionToken, FilterExpression> TryParse(
14+
TokenList<FilterExpressionToken> input)
15+
{
16+
return Expr.AtEnd().TryParse(input);
17+
}
18+
1219
static readonly TokenListParser<FilterExpressionToken, string> Add = Token.EqualTo(FilterExpressionToken.Plus).Value(Operators.OpAdd);
1320
static readonly TokenListParser<FilterExpressionToken, string> Subtract = Token.EqualTo(FilterExpressionToken.Minus).Value(Operators.OpSubtract);
1421
static readonly TokenListParser<FilterExpressionToken, string> Multiply = Token.EqualTo(FilterExpressionToken.Asterisk).Value(Operators.OpMultiply);
@@ -130,7 +137,7 @@ from factor in Factor
130137

131138
static readonly TokenListParser<FilterExpressionToken, FilterExpression> Disjunction = Parse.Chain(Or, Conjunction, MakeBinary);
132139

133-
public static readonly TokenListParser<FilterExpressionToken, FilterExpression> Expr = Disjunction;
140+
static readonly TokenListParser<FilterExpressionToken, FilterExpression> Expr = Disjunction;
134141

135142
static FilterExpression MakeBinary(string operatorName, FilterExpression leftOperand, FilterExpression rightOperand)
136143
{

src/Serilog.Filters.Expressions/Filters/Expressions/Parsing/FilterExpressionTokenizer.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class FilterExpressionTokenizer : Tokenizer<FilterExpressionToken>
2727
FilterExpressionToken.Is
2828
};
2929

30-
static readonly FilterExpressionKeyword[] SqlKeywords =
30+
static readonly FilterExpressionKeyword[] Keywords =
3131
{
3232
new FilterExpressionKeyword("and", FilterExpressionToken.And),
3333
new FilterExpressionKeyword("in", FilterExpressionToken.In),
@@ -61,7 +61,9 @@ static FilterExpressionTokenizer()
6161
SimpleOps['?'] = FilterExpressionToken.QuestionMark;
6262
}
6363

64-
protected override IEnumerable<Result<FilterExpressionToken>> Tokenize(TextSpan stringSpan)
64+
protected override IEnumerable<Result<FilterExpressionToken>> Tokenize(
65+
TextSpan stringSpan,
66+
TokenizationState<FilterExpressionToken> tokenizationState)
6567
{
6668
var next = SkipWhiteSpace(stringSpan);
6769
if (!next.HasValue)
@@ -88,7 +90,7 @@ protected override IEnumerable<Result<FilterExpressionToken>> Tokenize(TextSpan
8890
next = real.Remainder.ConsumeChar();
8991
}
9092

91-
if (next.HasValue && !char.IsPunctuation(next.Value) && !char.IsWhiteSpace(next.Value))
93+
if (!IsDelimiter(next))
9294
{
9395
yield return Result.Empty<FilterExpressionToken>(next.Location, new[] { "digit" });
9496
}
@@ -141,7 +143,9 @@ protected override IEnumerable<Result<FilterExpressionToken>> Tokenize(TextSpan
141143
yield return Result.Value(FilterExpressionToken.Identifier, beginIdentifier, next.Location);
142144
}
143145
}
144-
else if (next.Value == '/' && (!Previous.HasValue || PreRegexTokens.Contains(Previous.Kind)))
146+
else if (next.Value == '/' &&
147+
(!tokenizationState.Previous.HasValue ||
148+
PreRegexTokens.Contains(tokenizationState.Previous.Value.Kind)))
145149
{
146150
var regex = FilterExpressionTextParsers.RegularExpression(next.Location);
147151
if (!regex.HasValue)
@@ -174,9 +178,16 @@ protected override IEnumerable<Result<FilterExpressionToken>> Tokenize(TextSpan
174178
} while (next.HasValue);
175179
}
176180

181+
static bool IsDelimiter(Result<char> next)
182+
{
183+
return !next.HasValue ||
184+
char.IsWhiteSpace(next.Value) ||
185+
next.Value < SimpleOps.Length && SimpleOps[next.Value] != FilterExpressionToken.None;
186+
}
187+
177188
static bool TryGetKeyword(TextSpan span, out FilterExpressionToken keyword)
178189
{
179-
foreach (var kw in SqlKeywords)
190+
foreach (var kw in Keywords)
180191
{
181192
if (span.EqualsValueIgnoreCase(kw.Text))
182193
{
@@ -188,5 +199,7 @@ static bool TryGetKeyword(TextSpan span, out FilterExpressionToken keyword)
188199
keyword = FilterExpressionToken.None;
189200
return false;
190201
}
202+
203+
public static FilterExpressionTokenizer Instance { get; } = new FilterExpressionTokenizer();
191204
}
192205
}

src/Serilog.Filters.Expressions/Serilog.Filters.Expressions.csproj

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
<PropertyGroup>
44
<Description>Expression-based event filtering for Serilog.</Description>
5-
<VersionPrefix>1.1.1</VersionPrefix>
5+
<VersionPrefix>2.0.0</VersionPrefix>
66
<Authors>Serilog Contributors</Authors>
7-
<TargetFrameworks>net45;netstandard1.5</TargetFrameworks>
7+
<TargetFrameworks>net4.5;netstandard1.5</TargetFrameworks>
88
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
99
<GenerateDocumentationFile>true</GenerateDocumentationFile>
1010
<AssemblyName>Serilog.Filters.Expressions</AssemblyName>
@@ -14,18 +14,19 @@
1414
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
1515
<PackageId>Serilog.Filters.Expressions</PackageId>
1616
<PackageTags>serilog</PackageTags>
17-
<PackageIconUrl>http://serilog.net/images/serilog-extension-nuget.png</PackageIconUrl>
17+
<PackageIconUrl>https://serilog.net/images/serilog-extension-nuget.png</PackageIconUrl>
1818
<PackageProjectUrl>https://github.com/serilog/serilog-filters-expressions</PackageProjectUrl>
19-
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
20-
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
19+
<PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
20+
<DisableImplicitFrameworkReferences Condition=" '$(TargetFramework)' == 'net4.5' ">True</DisableImplicitFrameworkReferences>
21+
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.1</NetStandardImplicitPackageVersion>
2122
</PropertyGroup>
2223

2324
<ItemGroup>
24-
<PackageReference Include="Serilog" Version="2.3.0" />
25-
<PackageReference Include="Superpower" Version="1.0.1" />
25+
<PackageReference Include="Serilog" Version="2.7.1" />
26+
<PackageReference Include="Superpower" Version="2.0.0" />
2627
</ItemGroup>
2728

28-
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
29+
<ItemGroup Condition=" '$(TargetFramework)' == 'net4.5' ">
2930
<Reference Include="System" />
3031
<Reference Include="Microsoft.CSharp" />
3132
</ItemGroup>

test/Serilog.Filters.Expressions.PerformanceTests/Serilog.Filters.Expressions.PerformanceTests.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netcoreapp1.1;net462</TargetFrameworks>
4+
<TargetFrameworks>netcoreapp2.0;net4.6.2</TargetFrameworks>
55
<AssemblyName>Serilog.Filters.Expressions.PerformanceTests</AssemblyName>
66
<AssemblyOriginatorKeyFile>../../assets/Serilog.snk</AssemblyOriginatorKeyFile>
77
<SignAssembly>true</SignAssembly>
@@ -18,7 +18,7 @@
1818
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
1919
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
2020
<PackageReference Include="xunit" Version="2.3.1" />
21-
<PackageReference Include="BenchmarkDotNet" Version="0.10.9" />
21+
<PackageReference Include="BenchmarkDotNet" Version="0.10.14" />
2222
</ItemGroup>
2323

2424
<ItemGroup>

test/Serilog.Filters.Expressions.Tests/FilterExpressionParserTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class FilterExpressionParserTests
3838
[InlineData("@EventType = 0xC0ffee", "Equal(@EventType,12648430)")]
3939
[InlineData("@Level in ['Error', 'Warning']", "_Internal_In(@Level,[@\"Error\",@\"Warning\"])")]
4040
[InlineData("5 not in [1, 2]", "_Internal_NotIn(5,[1,2])")]
41+
[InlineData("1+1", "Add(1,1)")]
4142
public void ValidSyntaxIsAccepted(string input, string expected = null)
4243
{
4344
var roundTrip = FilterExpressionParser.Parse(input).ToString();
@@ -59,5 +60,16 @@ public void InvalidSyntaxIsRejected(string input)
5960
{
6061
Assert.Throws<ArgumentException>(() => FilterExpressionParser.Parse(input));
6162
}
63+
64+
[Theory]
65+
[InlineData("A = 'b", "Syntax error: unexpected end of input, expected `'`.")]
66+
[InlineData("A or B) and C", "Syntax error (line 1, column 7): unexpected `)`.")]
67+
[InlineData("A lik3 C", "Syntax error (line 1, column 3): unexpected identifier `lik3`.")]
68+
[InlineData("A > 1234f", "Syntax error (line 1, column 9): unexpected `f`, expected digit.")]
69+
public void PreciseErrorsAreReported(string input, string expectedMessage)
70+
{
71+
var ex = Assert.Throws<ArgumentException>(() => FilterExpressionParser.Parse(input));
72+
Assert.Equal(expectedMessage, ex.Message);
73+
}
6274
}
6375
}

test/Serilog.Filters.Expressions.Tests/PackagingTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class PackagingTests
99
public void AssemblyVersionIsSet()
1010
{
1111
var version = typeof(LoggerFilterConfigurationExtensions).GetTypeInfo().Assembly.GetName().Version;
12-
Assert.Equal("1", version.ToString(1));
12+
Assert.Equal("2", version.ToString(1));
1313
}
1414
}
1515
}
Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2-
32
<PropertyGroup>
4-
<TargetFrameworks>netcoreapp1.0;net452</TargetFrameworks>
3+
<TargetFrameworks>netcoreapp2.0;net4.6.2</TargetFrameworks>
54
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
65
<AssemblyName>Serilog.Filters.Expressions.Tests</AssemblyName>
76
<AssemblyOriginatorKeyFile>../../assets/Serilog.snk</AssemblyOriginatorKeyFile>
@@ -10,28 +9,19 @@
109
<PackageId>Serilog.Filters.Expressions.Tests</PackageId>
1110
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
1211
</PropertyGroup>
13-
14-
<ItemGroup>
15-
<None Include="App.config" />
16-
</ItemGroup>
17-
1812
<ItemGroup>
1913
<ProjectReference Include="..\..\src\Serilog.Filters.Expressions\Serilog.Filters.Expressions.csproj" />
2014
</ItemGroup>
21-
2215
<ItemGroup>
2316
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
2417
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
2518
<PackageReference Include="xunit" Version="2.3.1" />
2619
</ItemGroup>
27-
2820
<ItemGroup Condition=" '$(TargetFramework)' == 'net452' ">
2921
<Reference Include="System" />
3022
<Reference Include="Microsoft.CSharp" />
3123
</ItemGroup>
32-
3324
<ItemGroup>
3425
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
3526
</ItemGroup>
36-
37-
</Project>
27+
</Project>

test/Serilog.Filters.Expressions.Tests/app.config

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)