Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@
<PackageReference Include="StyleSharp.Analyzers" PrivateAssets="all"/>
<PackageReference Include="PerformanceSharp.Analyzers" PrivateAssets="all"/>
<PackageReference Include="SecuritySharp.Analyzers" PrivateAssets="all"/>
<PackageReference Include="Roslynator.Analyzers"/>
<PackageReference Include="SonarAnalyzer.CSharp"/>
<PackageReference Include="Blazor.Common.Analyzers"/>
<PackageReference Include="Roslynator.Analyzers" PrivateAssets="all"/>
<PackageReference Include="SonarAnalyzer.CSharp" PrivateAssets="all"/>
<PackageReference Include="Blazor.Common.Analyzers" PrivateAssets="all"/>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ namespace ReactiveUI.Binding.Expressions;
/// <item><description><see cref="ExpressionType.Convert"/> is stripped.</description></item>
/// </list>
/// </remarks>
[RequiresUnreferencedCode(
"Expression rewriting uses reflection over runtime types which may be removed by trimming.")]
internal sealed class ExpressionRewriter : ExpressionVisitor
{
/// <inheritdoc/>
Expand Down Expand Up @@ -141,8 +143,6 @@ internal Expression[] VisitArgumentList(ReadOnlyCollection<Expression> arguments
}

/// <inheritdoc/>
[RequiresUnreferencedCode(
"Expression rewriting uses reflection over runtime types which may be removed by trimming.")]
protected override Expression VisitBinary(BinaryExpression node)
{
if (node.Right is not ConstantExpression)
Expand All @@ -159,8 +159,6 @@ protected override Expression VisitBinary(BinaryExpression node)
}

/// <inheritdoc/>
[RequiresUnreferencedCode(
"Expression rewriting uses reflection over runtime types which may be removed by trimming.")]
protected override Expression VisitUnary(UnaryExpression node)
{
// Visit() only routes Convert and ArrayLength here, so no fallthrough is needed.
Expand All @@ -178,8 +176,6 @@ protected override Expression VisitUnary(UnaryExpression node)
}

/// <inheritdoc/>
[RequiresUnreferencedCode(
"Expression rewriting uses reflection over runtime types which may be removed by trimming.")]
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (!node.Method.IsSpecialName || !AllConstant(node.Arguments))
Expand Down
13 changes: 10 additions & 3 deletions src/ReactiveUI.Binding.Shared/Expression/Reflection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,24 @@ namespace ReactiveUI.Binding.Expressions;
/// <summary>Helper class for handling reflection and expression-tree related operations.</summary>
public static class Reflection
{
/// <summary>Singleton instance of the <see cref="ExpressionRewriter"/> used for rewriting expression trees.</summary>
/// <summary>Reported when an expression yields no chain to walk.</summary>
private const string EmptyExpressionChainMessage = "Expression chain must contain at least one element.";

/// <summary>The shared rewriter instance used to simplify expressions before inspection.</summary>
private static readonly ExpressionRewriter ExpressionRewriterInstance = new();
/// <remarks>
/// Built on first use rather than in a static initializer. The rewriter reads runtime types by
/// reflection and says so, and a static constructor has nowhere to carry that annotation.
/// </remarks>
private static ExpressionRewriter? _expressionRewriter;

/// <summary>Uses the expression re-writer to simplify the expression down to its simplest expression.</summary>
/// <param name="expression">The expression to rewrite.</param>
/// <returns>The rewritten expression.</returns>
[RequiresUnreferencedCode(
"Expression rewriting uses reflection over runtime types which may be removed by trimming.")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Expression Rewrite(Expression? expression) => ExpressionRewriterInstance.Visit(expression);
public static Expression Rewrite(Expression? expression) =>
(_expressionRewriter ??= new()).Visit(expression);

/// <summary>Converts an expression that points to a property chain into a dotted path string.</summary>
/// <param name="expression">The expression to generate the property names from.</param>
Expand Down
Loading