Skip to content

Commit

Permalink
WIP: More trimming annotations in DotNext.Metaprogramming.
Browse files Browse the repository at this point in the history
  • Loading branch information
alexrp committed Jan 30, 2024
1 parent af824ce commit e1e1790
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;

Expand Down Expand Up @@ -156,4 +157,4 @@ protected override CollectionAccessExpression VisitChildren(ExpressionVisitor vi
var collection = visitor.Visit(Collection);
return ReferenceEquals(index, Index) && ReferenceEquals(collection, Collection) ? this : new(collection, index);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace DotNext.Linq.Expressions;
/// Represents iteration over collection elements as expression.
/// </summary>
/// <seealso href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in">foreach Statement</seealso>
[RequiresUnreferencedCode("Dynamic access to GetEnumerator method and IEnumerable<T> interfaces.")]
[RequiresUnreferencedCode("Dynamic access to GetEnumerator (GetAsyncEnumerator) method and IEnumerable<T> (IAsyncEnumerable<T>) interfaces.")]
public sealed class ForEachExpression : CustomExpression, ILoopLabels
{
private const string EnumeratorVarName = "enumerator";
Expand Down Expand Up @@ -224,4 +224,4 @@ public override Expression Reduce()

return Reduce(moveNextCall, disposeCall);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Dynamic;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Linq.Expressions;
using System.Reflection;
using Debug = System.Diagnostics.Debug;
Expand All @@ -8,6 +9,7 @@ namespace DotNext.Linq.Expressions;

using Intrinsics = Runtime.Intrinsics;

[RequiresUnreferencedCode("Binds to arbitrary members.")]
internal sealed class MetaExpression : DynamicMetaObject
{
private static readonly MethodInfo AsExpressionBuilderMethod = new Func<object?, ISupplier<Expression>?>(Unsafe.As<ISupplier<Expression>>).Method;
Expand Down Expand Up @@ -178,4 +180,4 @@ public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder

return new MetaExpression(binding, CreateRestrictions().Merge(restrictions));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

namespace DotNext.Metaprogramming;

using System.Diagnostics.CodeAnalysis;
using Linq.Expressions;
using Runtime.CompilerServices;
using static Reflection.DelegateType;
using List = Collections.Generic.List;

internal sealed class AsyncLambdaExpression<TDelegate> : LambdaExpression, ILexicalScope<Expression<TDelegate>, Action<LambdaContext>>, ILexicalScope<Expression<TDelegate>, Action<LambdaContext, ParameterExpression>>
[RequiresUnreferencedCode("Dynamic access to Transition and IAsyncStateMachine internal types.")]
internal sealed class AsyncLambdaExpression<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TDelegate> : LambdaExpression, ILexicalScope<Expression<TDelegate>, Action<LambdaContext>>, ILexicalScope<Expression<TDelegate>, Action<LambdaContext, ParameterExpression>>
where TDelegate : Delegate
{
private readonly bool usePooling;
Expand Down Expand Up @@ -99,4 +101,4 @@ public override void Dispose()
recursion = null;
base.Dispose();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;

namespace DotNext.Metaprogramming;

using ForEachExpression = Linq.Expressions.ForEachExpression;

[RequiresUnreferencedCode("Dynamic access to GetAsyncEnumerator method and IAsyncEnumerable<T> interfaces.")]
internal sealed class AwaitForEachStatement : LoopLexicalScope, ILexicalScope<ForEachExpression, Action<MemberExpression>>, ILexicalScope<ForEachExpression, Action<MemberExpression, LoopContext>>
{
private readonly Expression collection;
Expand Down Expand Up @@ -33,4 +35,4 @@ internal AwaitForEachStatement(Expression collection, Expression? cancellationTo
result.Body = Build();
return result;
}
}
}
29 changes: 20 additions & 9 deletions src/DotNext.Metaprogramming/Metaprogramming/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ public static void NullSafeCall(Expression instance, MethodInfo method, params E
/// <param name="methodName">The method to be called.</param>
/// <param name="arguments">Method call arguments.</param>
/// <exception cref="InvalidOperationException">Attempts to call this method out of lexical scope.</exception>
[RequiresUnreferencedCode("Dynamically accesses method <methodName>.")]
public static void Call(Expression instance, string methodName, params Expression[] arguments)
=> Statement(instance.Call(methodName, arguments));

Expand All @@ -378,6 +379,7 @@ public static void Call(Expression instance, string methodName, params Expressio
/// <param name="methodName">The method to be called.</param>
/// <param name="arguments">Method call arguments.</param>
/// <exception cref="InvalidOperationException">Attempts to call this method out of lexical scope.</exception>
[RequiresUnreferencedCode("Dynamically accesses method <methodName>.")]
public static void NullSafeCall(Expression instance, string methodName, params Expression[] arguments)
=> Statement(instance.IfNotNull(target => target.Call(methodName, arguments)));

Expand Down Expand Up @@ -406,7 +408,8 @@ public static void CallStatic(MethodInfo method, params Expression[] arguments)
/// <param name="methodName">The name of the static method.</param>
/// <param name="arguments">The arguments to be passed into static method.</param>
/// <exception cref="InvalidOperationException">Attempts to call this method out of lexical scope.</exception>
public static void CallStatic(Type type, string methodName, params Expression[] arguments)
public static void CallStatic(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type, string methodName, params Expression[] arguments)
=> Statement(type.CallStatic(methodName, arguments));

/// <summary>
Expand All @@ -416,7 +419,7 @@ public static void CallStatic(Type type, string methodName, params Expression[]
/// <param name="methodName">The name of the static method.</param>
/// <param name="arguments">The arguments to be passed into static method.</param>
/// <exception cref="InvalidOperationException">Attempts to call this method out of lexical scope.</exception>
public static void CallStatic<T>(string methodName, params Expression[] arguments)
public static void CallStatic<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>(string methodName, params Expression[] arguments)
=> CallStatic(typeof(T), methodName, arguments);

/// <summary>
Expand Down Expand Up @@ -609,6 +612,7 @@ public static void DoWhile(Expression test, Action body)
/// <param name="body">Loop body.</param>
/// <exception cref="InvalidOperationException">Attempts to call this method out of lexical scope.</exception>
/// <seealso href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in">foreach Statement</seealso>
[RequiresUnreferencedCode("Dynamic access to GetEnumerator method and IEnumerable<T> interfaces.")]
public static void ForEach(Expression collection, Action<MemberExpression, LoopContext> body)
{
using var statement = new ForEachStatement(collection);
Expand All @@ -622,6 +626,7 @@ public static void ForEach(Expression collection, Action<MemberExpression, LoopC
/// <param name="body">Loop body.</param>
/// <exception cref="InvalidOperationException">Attempts to call this method out of lexical scope.</exception>
/// <seealso href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in">foreach Statement</seealso>
[RequiresUnreferencedCode("Dynamic access to GetEnumerator method and IEnumerable<T> interfaces.")]
public static void ForEach(Expression collection, Action<MemberExpression> body)
{
using var statement = new ForEachStatement(collection);
Expand All @@ -637,6 +642,7 @@ public static void ForEach(Expression collection, Action<MemberExpression> body)
/// <param name="configureAwait"><see langword="true"/> to call <see cref="ValueTask.ConfigureAwait(bool)"/> with <see langword="false"/> argument when awaiting <see cref="IAsyncEnumerator{T}.MoveNextAsync"/> method.</param>
/// <exception cref="InvalidOperationException">Attempts to call this method out of lexical scope.</exception>
/// <seealso href="https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#asynchronous-streams">Async Streams</seealso>
[RequiresUnreferencedCode("Dynamic access to GetAsyncEnumerator method and IAsyncEnumerable<T> interfaces.")]
public static void AwaitForEach(Expression collection, Action<MemberExpression, LoopContext> body, Expression? cancellationToken = null, bool configureAwait = false)
{
using var statement = new AwaitForEachStatement(collection, cancellationToken, configureAwait);
Expand All @@ -652,6 +658,7 @@ public static void AwaitForEach(Expression collection, Action<MemberExpression,
/// <param name="configureAwait"><see langword="true"/> to call <see cref="ValueTask.ConfigureAwait(bool)"/> with <see langword="false"/> argument when awaiting <see cref="IAsyncEnumerator{T}.MoveNextAsync"/> method.</param>
/// <exception cref="InvalidOperationException">Attempts to call this method out of lexical scope.</exception>
/// <seealso href="https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#asynchronous-streams">Async Streams</seealso>
[RequiresUnreferencedCode("Dynamic access to GetAsyncEnumerator method and IAsyncEnumerable<T> interfaces.")]
public static void AwaitForEach(Expression collection, Action<MemberExpression> body, Expression? cancellationToken = null, bool configureAwait = false)
{
using var statement = new AwaitForEachStatement(collection, cancellationToken, configureAwait);
Expand Down Expand Up @@ -934,7 +941,7 @@ public static void Return(Expression? result = null)
/// <param name="tailCall"><see langword="true"/> if the lambda expression will be compiled with the tail call optimization, otherwise <see langword="false"/>.</param>
/// <param name="body">Lambda function builder.</param>
/// <returns>Constructed lambda expression.</returns>
public static Expression<TDelegate> Lambda<TDelegate>(bool tailCall, Action<LambdaContext> body)
public static Expression<TDelegate> Lambda<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TDelegate>(bool tailCall, Action<LambdaContext> body)
where TDelegate : Delegate
{
using var expression = new LambdaExpression<TDelegate>(tailCall);
Expand All @@ -948,7 +955,7 @@ public static Expression<TDelegate> Lambda<TDelegate>(bool tailCall, Action<Lamb
/// <param name="tailCall"><see langword="true"/> if the lambda expression will be compiled with the tail call optimization, otherwise <see langword="false"/>.</param>
/// <param name="body">Lambda function builder.</param>
/// <returns>Constructed lambda expression.</returns>
public static Expression<TDelegate> Lambda<TDelegate>(bool tailCall, Func<LambdaContext, Expression> body)
public static Expression<TDelegate> Lambda<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TDelegate>(bool tailCall, Func<LambdaContext, Expression> body)
where TDelegate : Delegate
{
using var expression = new LambdaExpression<TDelegate>(tailCall);
Expand All @@ -961,7 +968,7 @@ public static Expression<TDelegate> Lambda<TDelegate>(bool tailCall, Func<Lambda
/// <typeparam name="TDelegate">The delegate describing signature of lambda function.</typeparam>
/// <param name="body">Lambda function builder.</param>
/// <returns>Constructed lambda expression.</returns>
public static Expression<TDelegate> Lambda<TDelegate>(Func<LambdaContext, Expression> body)
public static Expression<TDelegate> Lambda<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TDelegate>(Func<LambdaContext, Expression> body)
where TDelegate : Delegate
=> Lambda<TDelegate>(false, body);

Expand All @@ -972,7 +979,7 @@ public static Expression<TDelegate> Lambda<TDelegate>(Func<LambdaContext, Expres
/// <param name="tailCall"><see langword="true"/> if the lambda expression will be compiled with the tail call optimization, otherwise <see langword="false"/>.</param>
/// <param name="body">Lambda function builder.</param>
/// <returns>Constructed lambda expression.</returns>
public static Expression<TDelegate> Lambda<TDelegate>(bool tailCall, Action<LambdaContext, ParameterExpression> body)
public static Expression<TDelegate> Lambda<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TDelegate>(bool tailCall, Action<LambdaContext, ParameterExpression> body)
where TDelegate : Delegate
{
using var expression = new LambdaExpression<TDelegate>(tailCall);
Expand All @@ -985,7 +992,7 @@ public static Expression<TDelegate> Lambda<TDelegate>(bool tailCall, Action<Lamb
/// <typeparam name="TDelegate">The delegate describing signature of lambda function.</typeparam>
/// <param name="body">Lambda function builder.</param>
/// <returns>Constructed lambda expression.</returns>
public static Expression<TDelegate> Lambda<TDelegate>(Action<LambdaContext> body)
public static Expression<TDelegate> Lambda<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TDelegate>(Action<LambdaContext> body)
where TDelegate : Delegate
=> Lambda<TDelegate>(false, body);

Expand All @@ -995,7 +1002,7 @@ public static Expression<TDelegate> Lambda<TDelegate>(Action<LambdaContext> body
/// <typeparam name="TDelegate">The delegate describing signature of lambda function.</typeparam>
/// <param name="body">Lambda function builder.</param>
/// <returns>Constructed lambda expression.</returns>
public static Expression<TDelegate> Lambda<TDelegate>(Action<LambdaContext, ParameterExpression> body)
public static Expression<TDelegate> Lambda<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TDelegate>(Action<LambdaContext, ParameterExpression> body)
where TDelegate : Delegate
=> Lambda<TDelegate>(false, body);

Expand All @@ -1008,6 +1015,7 @@ public static Expression<TDelegate> Lambda<TDelegate>(Action<LambdaContext, Para
/// <seealso cref="AwaitExpression"/>
/// <seealso cref="AsyncResultExpression"/>
/// <seealso href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/#BKMK_HowtoWriteanAsyncMethod">Async methods</seealso>
[RequiresUnreferencedCode("Dynamic access to Transition and IAsyncStateMachine internal types.")]
public static Expression<TDelegate> AsyncLambda<TDelegate>(Action<LambdaContext> body)
where TDelegate : Delegate
=> AsyncLambda<TDelegate>(false, body);
Expand All @@ -1025,6 +1033,7 @@ public static Expression<TDelegate> AsyncLambda<TDelegate>(Action<LambdaContext>
/// <seealso cref="AwaitExpression"/>
/// <seealso cref="AsyncResultExpression"/>
/// <seealso href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/#BKMK_HowtoWriteanAsyncMethod">Async methods</seealso>
[RequiresUnreferencedCode("Dynamic access to Transition and IAsyncStateMachine internal types.")]
public static Expression<TDelegate> AsyncLambda<TDelegate>(bool usePooling, Action<LambdaContext> body)
where TDelegate : Delegate
=> new AsyncLambdaExpression<TDelegate>(usePooling).Build(body);
Expand All @@ -1038,6 +1047,7 @@ public static Expression<TDelegate> AsyncLambda<TDelegate>(bool usePooling, Acti
/// <seealso cref="AwaitExpression"/>
/// <seealso cref="AsyncResultExpression"/>
/// <seealso href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/#BKMK_HowtoWriteanAsyncMethod">Async methods</seealso>
[RequiresUnreferencedCode("Dynamic access to Transition and IAsyncStateMachine internal types.")]
public static Expression<TDelegate> AsyncLambda<TDelegate>(Action<LambdaContext, ParameterExpression> body)
where TDelegate : Delegate
=> AsyncLambda<TDelegate>(false, body);
Expand All @@ -1055,6 +1065,7 @@ public static Expression<TDelegate> AsyncLambda<TDelegate>(Action<LambdaContext,
/// <seealso cref="AwaitExpression"/>
/// <seealso cref="AsyncResultExpression"/>
/// <seealso href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/#BKMK_HowtoWriteanAsyncMethod">Async methods</seealso>
[RequiresUnreferencedCode("Dynamic access to Transition and IAsyncStateMachine internal types.")]
public static Expression<TDelegate> AsyncLambda<TDelegate>(bool usePooling, Action<LambdaContext, ParameterExpression> body)
where TDelegate : Delegate
=> new AsyncLambdaExpression<TDelegate>(usePooling).Build(body);
Expand Down Expand Up @@ -1104,4 +1115,4 @@ public static LambdaExpressionTree AsyncLambda(Type[] parameters, Type returnTyp
/// <param name="expr">The expression to add.</param>
public static void Statement(Expression expr)
=> LexicalScope.Current.AddStatement(expr);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System.Linq.Expressions;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;

namespace DotNext.Metaprogramming;

using ForEachExpression = Linq.Expressions.ForEachExpression;

[RequiresUnreferencedCode("Dynamic access to GetEnumerator method and IEnumerable<T> interfaces.")]
internal sealed class ForEachStatement : LoopLexicalScope, ILexicalScope<ForEachExpression, Action<MemberExpression>>, ILexicalScope<ForEachExpression, Action<MemberExpression, LoopContext>>
{
private readonly Expression collection;
Expand All @@ -26,4 +28,4 @@ internal sealed class ForEachStatement : LoopLexicalScope, ILexicalScope<ForEach
result.Body = Build();
return result;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;

namespace DotNext.Metaprogramming;
Expand Down Expand Up @@ -43,7 +44,7 @@ private protected static IReadOnlyList<ParameterExpression> GetParameters(System
/// Represents lambda function builder.
/// </summary>
/// <typeparam name="TDelegate">The delegate describing signature of lambda function.</typeparam>
internal sealed class LambdaExpression<TDelegate> : LambdaExpression, ILexicalScope<Expression<TDelegate>, Action<LambdaContext>>, ILexicalScope<Expression<TDelegate>, Action<LambdaContext, ParameterExpression>>, ILexicalScope<Expression<TDelegate>, Func<LambdaContext, Expression>>
internal sealed class LambdaExpression<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TDelegate> : LambdaExpression, ILexicalScope<Expression<TDelegate>, Action<LambdaContext>>, ILexicalScope<Expression<TDelegate>, Action<LambdaContext, ParameterExpression>>, ILexicalScope<Expression<TDelegate>, Func<LambdaContext, Expression>>
where TDelegate : Delegate
{
private readonly Type returnType;
Expand Down Expand Up @@ -148,4 +149,4 @@ public override void Dispose()
recursion = null;
base.Dispose();
}
}
}

0 comments on commit e1e1790

Please sign in to comment.