Skip to content

Commit

Permalink
Merge pull request #117 from nblumhardt/v4-updates
Browse files Browse the repository at this point in the history
Update to Serilog 4, tidy up
  • Loading branch information
nblumhardt authored Jun 4, 2024
2 parents ed917a8 + fde5bfb commit 3198122
Show file tree
Hide file tree
Showing 46 changed files with 190 additions and 151 deletions.
1 change: 1 addition & 0 deletions serilog-expressions.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CI/@EntryIndexedValue">CI</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Acerola/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Comparand/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=delim/@EntryIndexedValue">True</s:Boolean>
Expand Down
8 changes: 8 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/AccessorExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// An accessor retrieves a property from a (structured) object. For example, in the expression
/// <code>Headers.ContentType</code> the <code>.</code> operator forms an accessor expression that
/// retrieves the <code>ContentType</code> property from the <code>Headers</code> object.
/// </summary>
/// <remarks>Note that the AST type can represent accessors that cannot be validly written using
/// <code>.</code> notation. In these cases, if the accessor is formatted back out as an expression,
/// <see cref="IndexerExpression"/> notation will be used.</remarks>
class AccessorExpression : Expression
{
public AccessorExpression(Expression receiver, string memberName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// An ambient name is generally a property name or built-in that appears standalone in an expression. For example,
/// in <code>Headers.ContentType</code>, <code>Headers</code> is an ambient name that produces an
/// <see cref="AmbientNameExpression"/>. Built-ins like <code>@Level</code> are also parsed as ambient names.
/// </summary>
class AmbientNameExpression : Expression
{
readonly bool _requiresEscape;
Expand Down
7 changes: 7 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/ArrayExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// An array expression constructs an array from a list of elements. For example, <code>[1, 2, 3]</code> is an
/// array expression. The items in an array expression can be literal values or expressions, like in the
/// above example, or they can be spread expressions that describe zero or more elements to include in the
/// list. Whether included via regular elements or spread expressions, undefined values are ignored and won't
/// appear in the resulting array value.
/// </summary>
class ArrayExpression : Expression
{
public ArrayExpression(Element[] elements)
Expand Down
4 changes: 4 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/CallExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// A <see cref="CallExpression"/> is a function call made up of the function name, parenthesised argument
/// list, and optional postfix <code>ci</code> modifier. For example, <code>Substring(RequestPath, 0, 5)</code>.
/// </summary>
class CallExpression : Expression
{
public CallExpression(bool ignoreCase, string operatorName, params Expression[] operands)
Expand Down
22 changes: 10 additions & 12 deletions src/Serilog.Expressions/Expressions/Ast/ConstantExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// A constant such as <code>'hello'</code>, <code>true</code>, <code>null</code>, or <code>123.45</code>.
/// </summary>
class ConstantExpression : Expression
{
public ConstantExpression(LogEventPropertyValue constant)
Expand All @@ -30,19 +33,14 @@ public override string ToString()
{
if (Constant is ScalarValue sv)
{
switch (sv.Value)
return sv.Value switch
{
case string s:
return "'" + s.Replace("'", "''") + "'";
case true:
return "true";
case false:
return "false";
case IFormattable formattable:
return formattable.ToString(null, CultureInfo.InvariantCulture);
default:
return (sv.Value ?? "null").ToString() ?? "<ToString() returned null>";
}
string s => "'" + s.Replace("'", "''") + "'",
true => "true",
false => "false",
IFormattable formattable => formattable.ToString(null, CultureInfo.InvariantCulture),
_ => (sv.Value ?? "null").ToString() ?? "<ToString() returned null>"
};
}

return Constant.ToString();
Expand Down
7 changes: 4 additions & 3 deletions src/Serilog.Expressions/Expressions/Ast/Element.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

namespace Serilog.Expressions.Ast;

abstract class Element
{
}
/// <summary>
/// An element in an <see cref="ArrayExpression"/>.
/// </summary>
abstract class Element;
9 changes: 8 additions & 1 deletion src/Serilog.Expressions/Expressions/Ast/Expression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// An AST node.
/// </summary>
abstract class Expression
{
// Used only as an enabler for testing and debugging.
/// <summary>
/// The <see cref="ToString"/> representation of an <see cref="Expression"/> is <strong>not</strong>
/// guaranteed to be syntactically valid: this is provided for debugging purposes only.
/// </summary>
/// <returns>A textual representation of the expression.</returns>
public abstract override string ToString();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// A non-syntax expression tree node used when compiling the <see cref="Operators.OpIndexOfMatch"/>,
/// <see cref="Operators.OpIsMatch"/>, and SQL-style <code>like</code> expressions.
/// </summary>
class IndexOfMatchExpression : Expression
{
public Expression Corpus { get; }
Expand Down
5 changes: 5 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/IndexerExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// An <see cref="IndexerExpression"/> retrieves a property from an object, by name, or an item from an array
/// by zero-based numeric index. For example, <code>Headers['Content-Type']</code> and <code>Items[2]</code> are
/// parsed as indexer expressions.
/// </summary>
class IndexerExpression : Expression
{
public Expression Receiver { get; }
Expand Down
3 changes: 3 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/IndexerWildcard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// Describes the wildcard in a <see cref="IndexerWildcardExpression"/>.
/// </summary>
enum IndexerWildcard { Undefined, Any, All }
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// An indexer wildcard is a placeholder in a property path expression. For example,
/// in <code>Headers[?] = 'test'</code>, the question-mark token is a wildcard that means "any property of
/// the <code>Headers</code> object". The other wildcard indexer is the asterisk, meaning "all".
/// </summary>
class IndexerWildcardExpression : Expression
{
public IndexerWildcardExpression(IndexerWildcard wildcard)
Expand Down
3 changes: 3 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/ItemElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// A single item in an <see cref="ArrayExpression"/>.
/// </summary>
class ItemElement : Element
{
public Expression Value { get; }
Expand Down
4 changes: 4 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/LambdaExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// A non-syntax expression tree node used in the compilation of <see cref="IndexerWildcardExpression"/>. Only
/// very limited support for lambda expressions is currently present.
/// </summary>
class LambdaExpression : Expression
{
public LambdaExpression(ParameterExpression[] parameters, Expression body)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// Represents the iteration variable in template <code>#each</code> directives.
/// </summary>
class LocalNameExpression : Expression
{
public LocalNameExpression(string name)
Expand Down
7 changes: 4 additions & 3 deletions src/Serilog.Expressions/Expressions/Ast/Member.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

namespace Serilog.Expressions.Ast;

abstract class Member
{
}
/// <summary>
/// A member in an <see cref="ObjectExpression"/>.
/// </summary>
abstract class Member;
5 changes: 5 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/ObjectExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// Constructs an object given a list of members. Members can be <code>name: value</code> pairs, or spread
/// expressions that include members from another object. Where names conflict, the rightmost appearance of
/// a name wins. Members that evaluate to an undefined value do not appear in the resulting object.
/// </summary>
class ObjectExpression : Expression
{
public ObjectExpression(Member[] members)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// Non-syntax expression type used to represent parameters in <see cref="LambdaExpression"/> bodies.
/// </summary>
class ParameterExpression : Expression
{
public ParameterExpression(string parameterName)
Expand Down
5 changes: 5 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/PropertyMember.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// An <see cref="ObjectExpression"/> member comprising an optionally-quoted name and a value, for example
/// the object <code>{Username: 'alice'}</code> includes a single <see cref="PropertyMember"/> with name
/// <code>Username</code> and value <code>'alice'</code>.
/// </summary>
class PropertyMember : Member
{
public string Name { get; }
Expand Down
7 changes: 7 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/SpreadElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// An element in an <see cref="ArrayExpression"/> that describes zero or more items to include in the array.
/// Spread elements are written with two dots preceding an expression that evaluates to an array of elements to
/// insert into the result array at the position of the spread element, for example, in <code>[1, 2, ..Others]</code>,
/// the <code>..Others</code> expression is a spread element. If the value of the array in the spread is
/// undefined, no items will be added to the list.
/// </summary>
class SpreadElement : Element
{
public Expression Content { get; }
Expand Down
5 changes: 5 additions & 0 deletions src/Serilog.Expressions/Expressions/Ast/SpreadMember.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

namespace Serilog.Expressions.Ast;

/// <summary>
/// An <see cref="ObjectExpression"/> member that designates another object from which to copy members into the
/// current object. Spread member expressions comprise two dots preceding an expression that is expected to
/// evaluate to an object.
/// </summary>
class SpreadMember : Member
{
public Expression Content { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static NameResolver Build(NameResolver? additionalNameResolver)
{
var defaultResolver = new StaticMemberNameResolver(typeof(RuntimeOperators));
return additionalNameResolver == null
? (NameResolver) defaultResolver
? defaultResolver
: new OrderedNameResolver(new[] {defaultResolver, additionalNameResolver });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ static ExpressionBody CompileLogical(Func<ExpressionBody, ExpressionBody, Expres
{
return LX.Convert(
LX.New(
typeof(ScalarValue).GetConstructor(new[]{typeof(object)})!,
typeof(ScalarValue).GetConstructor([typeof(object)])!,
LX.Convert(apply(
LX.Call(CoerceToScalarBooleanMethod, lhs),
LX.Call(CoerceToScalarBooleanMethod, rhs)), typeof(object))),
Expand Down Expand Up @@ -253,7 +253,7 @@ protected override ExpressionBody Transform(Ast.LambdaExpression lmx)
var lambda = LX.Lambda(delegateType, rewritten!, parameters.Select(px => px.Item2).ToArray());

// Unfortunately, right now, functions need to be threaded through in constant scalar values :-D
return LX.New(typeof(ScalarValue).GetConstructor(new[] {typeof(object)})!,
return LX.New(typeof(ScalarValue).GetConstructor([typeof(object)])!,
LX.Convert(lambda, typeof(object)));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ParameterReplacementVisitor : ExpressionVisitor
public static Expression ReplaceParameters(LambdaExpression lambda, params ParameterExpression[] newParameters)
{
var v = new ParameterReplacementVisitor(lambda.Parameters.ToArray(), newParameters);
return v.Visit(lambda.Body);
return v.Visit(lambda.Body)!;
}

ParameterReplacementVisitor(ParameterExpression[] from, ParameterExpression[] to)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ protected override Expression Transform(CallExpression call)

Expression TryCompileLikeExpression(bool ignoreCase, Expression corpus, Expression like)
{
if (like is ConstantExpression cx &&
cx.Constant is ScalarValue scalar &&
scalar.Value is string s)
if (like is ConstantExpression { Constant: ScalarValue { Value: string s } })
{
var regex = LikeToRegex(s);
var opts = RegexOptions.Compiled | RegexOptions.ExplicitCapture;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ protected override Expression Transform(CallExpression call)

Expression TryCompileIndexOfMatch(bool ignoreCase, Expression corpus, Expression regex)
{
if (regex is ConstantExpression cx &&
cx.Constant is ScalarValue scalar &&
scalar.Value is string s)
if (regex is ConstantExpression { Constant: ScalarValue { Value: string s } })
{
var opts = RegexOptions.Compiled | RegexOptions.ExplicitCapture;
if (ignoreCase)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ protected override Expression Transform(CallExpression lx)
comparisonArgs[indexerOperand] = nestedComparand;
var body = new CallExpression(lx.IgnoreCase, lx.OperatorName, comparisonArgs);

var lambda = new LambdaExpression(new[] { px }, body);
var lambda = new LambdaExpression([px], body);

var op = Operators.ToRuntimeWildcardOperator(wc);
var call = new CallExpression(false, op, coll, lambda);
Expand All @@ -84,7 +84,7 @@ protected override Expression Transform(IndexerExpression ix)

var px = new ParameterExpression("p" + _nextParameter++);
var coll = Transform(ix.Receiver);
var lambda = new LambdaExpression(new[] { px }, px);
var lambda = new LambdaExpression([px], px);
var op = Operators.ToRuntimeWildcardOperator(wx.Wildcard);
return new CallExpression(false, op, coll, lambda);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Serilog.Expressions/Expressions/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace Serilog.Expressions
/// <summary>
/// Helper methods.
/// </summary>
internal static class Helpers
static class Helpers
{
/// <summary>
/// Backport .NET Standard 2.1 additions to maintain .NET Standard 2.0 compatibility.
Expand All @@ -35,7 +35,7 @@ internal static class Helpers
/// <returns></returns>
public static bool Contains(this string source, string value, StringComparison comparisonType)
{
return source?.IndexOf(value, comparisonType) >= 0;
return source.IndexOf(value, comparisonType) >= 0;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ static class ExpressionTextParsers

public static readonly TextParser<string> HexInteger =
Span.EqualTo("0x")
.IgnoreThen(Character.Digit.Or(Character.Matching(ch => ch >= 'a' && ch <= 'f' || ch >= 'A' && ch <= 'F', "a-f"))
.IgnoreThen(Character.Digit.Or(Character.Matching(ch => ch is >= 'a' and <= 'f' or >= 'A' and <= 'F', "a-f"))
.Named("hex digit")
.AtLeastOnce())
.Select(chars => new string(chars));
Expand Down
Loading

0 comments on commit 3198122

Please sign in to comment.