diff --git a/src/DotNext.Metaprogramming/DotNext.Metaprogramming.csproj b/src/DotNext.Metaprogramming/DotNext.Metaprogramming.csproj
index 9cbc9292f..e62aa45b4 100644
--- a/src/DotNext.Metaprogramming/DotNext.Metaprogramming.csproj
+++ b/src/DotNext.Metaprogramming/DotNext.Metaprogramming.csproj
@@ -6,9 +6,9 @@
latest
enable
true
- false
+ true
nullablePublicOnly
- 5.0.1
+ 5.0.2
.NET Foundation
.NEXT Family of Libraries
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/CollectionAccessExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/CollectionAccessExpression.cs
index 90ac36a39..e375307d8 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/CollectionAccessExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/CollectionAccessExpression.cs
@@ -1,4 +1,5 @@
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
@@ -138,11 +139,11 @@ public override Expression Reduce()
if (indexer is null)
result = ArrayAccess(temp ?? Collection, Index);
else if (count is null)
- result = MakeIndex(temp ?? Collection, indexer, new[] { Index.Reduce() });
+ result = MakeIndex(temp ?? Collection, indexer, [Index.Reduce()]);
else
- result = MakeIndex(temp ?? Collection, indexer, new[] { MakeIndex(temp ?? Collection, count, Index) });
+ result = MakeIndex(temp ?? Collection, indexer, [MakeIndex(temp ?? Collection, count, Index)]);
- return temp is null ? result : Block(Type, new[] { temp }, Assign(temp, Collection), result);
+ return temp is null ? result : Block(Type, [temp], Assign(temp, Collection), result);
}
///
@@ -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);
}
-}
\ No newline at end of file
+}
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/ExpressionBuilder.cs b/src/DotNext.Metaprogramming/Linq/Expressions/ExpressionBuilder.cs
index 172c2fcb5..f479ab686 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/ExpressionBuilder.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/ExpressionBuilder.cs
@@ -251,6 +251,7 @@ public static BinaryExpression NotEqual(this Expression left, Expression right)
///
/// The operand.
/// check operation.
+ [RequiresUnreferencedCode("Dynamic access to properties of .")]
public static Expression IsNull(this Expression operand)
{
// handle nullable value type
@@ -277,6 +278,7 @@ public static Expression IsNull(this Expression operand)
///
/// The operand.
/// check operation.
+ [RequiresUnreferencedCode("Dynamic access to properties of .")]
public static Expression IsNotNull(this Expression operand)
{
// handle nullable value type
@@ -723,6 +725,7 @@ public static MethodCallExpression Call(this Expression instance, MethodInfo met
/// The name of the method to be called.
/// The method arguments.
/// The method call expression.
+ [RequiresUnreferencedCode("Dynamic access to the method identified by parameter.")]
public static MethodCallExpression Call(this Expression instance, string methodName, params Expression[] arguments)
=> instance.Call(instance.Type, methodName, arguments);
@@ -739,7 +742,7 @@ public static MethodCallExpression Call(this Expression instance, string methodN
/// The name of the method in the interface or base class to be called.
/// The method arguments.
/// The method call expression.
- public static MethodCallExpression Call(this Expression instance, Type interfaceType, string methodName, params Expression[] arguments)
+ public static MethodCallExpression Call(this Expression instance, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type interfaceType, string methodName, params Expression[] arguments)
{
if (!interfaceType.IsAssignableFrom(instance.Type))
throw new ArgumentException(ExceptionMessages.InterfaceNotImplemented(instance.Type, interfaceType));
@@ -756,7 +759,7 @@ public static MethodCallExpression Call(this Expression instance, Type interface
/// The name of the static method.
/// The arguments to be passed into static method.
/// An expression representing static method call.
- public static MethodCallExpression CallStatic(this Type type, string methodName, params Expression[] arguments)
+ public static MethodCallExpression CallStatic([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] this Type type, string methodName, params Expression[] arguments)
{
return type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly, null, Array.ConvertAll(arguments, GetType), null) is { } method
? Expression.Call(method, arguments)
@@ -799,7 +802,7 @@ public static IndexExpression Property(this Expression instance, PropertyInfo pr
/// The interface or base class declaring property.
/// The name of the instance property.
/// Property access expression.
- public static MemberExpression Property(this Expression instance, Type interfaceType, string propertyName)
+ public static MemberExpression Property(this Expression instance, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type interfaceType, string propertyName)
{
return interfaceType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance) is { } property
? Property(instance, property)
@@ -818,7 +821,7 @@ public static MemberExpression Property(this Expression instance, Type interface
/// The first index.
/// The rest of the indexer arguments.
/// Property access expression.
- public static IndexExpression Property(this Expression instance, Type interfaceType, string propertyName, Expression index0, params Expression[] indicies)
+ public static IndexExpression Property(this Expression instance, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type interfaceType, string propertyName, Expression index0, params Expression[] indicies)
{
return interfaceType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance) is { } property
? Property(instance, property, index0, indicies)
@@ -834,6 +837,7 @@ public static IndexExpression Property(this Expression instance, Type interfaceT
/// this argument.
/// The name of the instance property.
/// Property access expression.
+ [RequiresUnreferencedCode("Dynamic access to the property identified by parameter.")]
public static MemberExpression Property(this Expression instance, string propertyName)
=> Expression.Property(instance, propertyName);
@@ -848,6 +852,7 @@ public static MemberExpression Property(this Expression instance, string propert
/// The first index.
/// The rest of the indexer arguments.
/// Property access expression.
+ [RequiresUnreferencedCode("Dynamic access to the indexer identified by parameter.")]
public static IndexExpression Property(this Expression instance, string propertyName, Expression index0, params Expression[] indicies)
=> Expression.Property(instance, propertyName, [index0, .. indicies]);
@@ -872,6 +877,7 @@ public static MemberExpression Field(this Expression instance, FieldInfo field)
/// this argument.
/// The name of the instance field.
/// Field access expression.
+ [RequiresUnreferencedCode("Dynamic access to the field identified by parameter.")]
public static MemberExpression Field(this Expression instance, string fieldName)
=> Expression.Field(instance, fieldName);
@@ -937,10 +943,12 @@ public static UnaryExpression ArrayLength(this Expression array)
///
/// The expression representing collection.
/// The expression providing access to the appropriate property indicating the number of items in the collection.
+ [RequiresUnreferencedCode("Dynamic access to implemented interfaces and public properties of .")]
public static MemberExpression Count(this Expression collection)
{
if (collection.Type == typeof(string) || collection.Type == typeof(StringBuilder))
return Expression.Property(collection, nameof(string.Length));
+
var interfaceType = collection.Type.GetImplementedCollection() ?? throw new ArgumentException(ExceptionMessages.CollectionImplementationExpected);
return Expression.Property(collection, interfaceType, nameof(Count));
}
@@ -950,6 +958,7 @@ public static MemberExpression Count(this Expression collection)
///
/// The object to be converted into string.
/// The expression representing ToString() method call.
+ [RequiresUnreferencedCode("Dynamic access to public methods of .")]
public static MethodCallExpression AsString(this Expression obj) => Call(obj, nameof(ToString));
///
@@ -1136,12 +1145,12 @@ public static ConditionalExpression Condition(this Expression test, Exp
/// The type to be instantiated.
/// The list of arguments to be passed into constructor.
/// Instantiation expression.
- public static NewExpression New(this Type type, params Expression[] args)
+ public static NewExpression New([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] this Type type, params Expression[] args)
{
if (args.LongLength is 0L)
return Expression.New(type);
- return type.GetConstructor(Array.ConvertAll(args, static arg => arg.Type)) is { } ctor
+ return type.GetConstructor(Array.ConvertAll(args, GetType)) is { } ctor
? Expression.New(ctor, args)
: throw new MissingMethodException(type.FullName, ConstructorInfo.ConstructorName);
}
@@ -1155,6 +1164,7 @@ public static NewExpression New(this Type type, params Expression[] args)
/// An expression representing object construction.
/// A collection of members to initialize.
/// Initialization expression.
+ [RequiresUnreferencedCode("Dynamic access to public properties of .")]
public static MemberInitExpression Init(this NewExpression expression, MemberBindings bindings)
=> Expression.MemberInit(expression, bindings.Bind(expression.Type));
@@ -1203,10 +1213,10 @@ internal static Expression AddEpilogue(this Expression expression, bool inferTyp
/// The expression representing the type to be instantiated.
/// The list of arguments to be passed into constructor.
/// Instantiation expression.
- [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(Activator))]
+ [RequiresUnreferencedCode("Dynamic access to public constructors of a type represented by .")]
public static MethodCallExpression New(this Expression type, params Expression[] args)
{
- var activate = typeof(Activator).GetMethod(nameof(Activator.CreateInstance), new[] { typeof(Type), typeof(object[]) });
+ var activate = typeof(Activator).GetMethod(nameof(Activator.CreateInstance), [typeof(Type), typeof(object[])]);
Debug.Assert(activate is not null);
return Expression.Call(activate, type, Expression.NewArrayInit(typeof(object), args));
}
@@ -1217,6 +1227,7 @@ public static MethodCallExpression New(this Expression type, params Expression[]
/// The collection to iterate through.
/// A delegate that is used to construct the body of the loop.
/// The constructed loop.
+ [RequiresUnreferencedCode("Dynamic access to GetEnumerator method and IEnumerable interfaces.")]
public static ForEachExpression ForEach(this Expression collection, ForEachExpression.Statement body)
=> ForEachExpression.Create(collection, body);
@@ -1453,18 +1464,20 @@ public static Expression AsOptional(this Expression expression)
///
/// The compound expression.
/// The expression of type .
+ [RequiresUnreferencedCode("Dynamic access to DotNext.Result<> data type")]
public static Expression AsResult(this Expression expression)
{
var exception = Expression.Parameter(typeof(Exception));
- var ctor = typeof(Result<>).MakeGenericType(expression.Type).GetConstructor(new[] { expression.Type });
+ var ctor = typeof(Result<>).MakeGenericType(expression.Type).GetConstructor([expression.Type]);
Debug.Assert(ctor?.DeclaringType is not null);
- var fallbackCtor = ctor.DeclaringType.GetConstructor(new[] { typeof(Exception) });
+ var fallbackCtor = ctor.DeclaringType.GetConstructor([typeof(Exception)]);
Debug.Assert(fallbackCtor is not null);
return Expression.TryCatch(
Expression.New(ctor, expression),
Expression.Catch(exception, Expression.New(fallbackCtor, exception)));
}
+ [RequiresUnreferencedCode("Dynamic access to indexer of .")]
internal static IndexExpression MakeIndex(Expression target, Expression[] args)
{
// handle case for array
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/ForEachExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/ForEachExpression.cs
index 373c0bc41..919262221 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/ForEachExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/ForEachExpression.cs
@@ -1,5 +1,6 @@
using System.Collections;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
@@ -13,6 +14,7 @@ namespace DotNext.Linq.Expressions;
/// Represents iteration over collection elements as expression.
///
/// foreach Statement
+[RequiresUnreferencedCode("Dynamic access to GetEnumerator (GetAsyncEnumerator) method and IEnumerable (IAsyncEnumerable) interfaces.")]
public sealed class ForEachExpression : CustomExpression, ILoopLabels
{
private const string EnumeratorVarName = "enumerator";
@@ -222,4 +224,4 @@ public override Expression Reduce()
return Reduce(moveNextCall, disposeCall);
}
-}
\ No newline at end of file
+}
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/InterpolationExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/InterpolationExpression.cs
index 76d983426..aa8f1b3f8 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/InterpolationExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/InterpolationExpression.cs
@@ -105,19 +105,19 @@ private Expression MakePlainString()
case 0:
return Constant(Format);
case 1:
- var formatMethod = typeof(string).GetMethod(nameof(string.Format), new[] { typeof(IFormatProvider), typeof(string), typeof(object) });
+ var formatMethod = typeof(string).GetMethod(nameof(string.Format), [typeof(IFormatProvider), typeof(string), typeof(object)]);
Debug.Assert(formatMethod is not null);
return Call(formatMethod, FormatProvider, Constant(Format), arguments[0]);
case 2:
- formatMethod = typeof(string).GetMethod(nameof(string.Format), new[] { typeof(IFormatProvider), typeof(string), typeof(object), typeof(object) });
+ formatMethod = typeof(string).GetMethod(nameof(string.Format), [typeof(IFormatProvider), typeof(string), typeof(object), typeof(object)]);
Debug.Assert(formatMethod is not null);
return Call(formatMethod, FormatProvider, Constant(Format), FormatProvider, arguments[0], arguments[1]);
case 3:
- formatMethod = typeof(string).GetMethod(nameof(string.Format), new[] { typeof(IFormatProvider), typeof(string), typeof(object), typeof(object), typeof(object) });
+ formatMethod = typeof(string).GetMethod(nameof(string.Format), [typeof(IFormatProvider), typeof(string), typeof(object), typeof(object), typeof(object)]);
Debug.Assert(formatMethod is not null);
return Call(formatMethod, FormatProvider, Constant(Format), FormatProvider, arguments[0], arguments[1], arguments[2]);
default:
- formatMethod = typeof(string).GetMethod(nameof(string.Format), new[] { typeof(IFormatProvider), typeof(string), typeof(object[]) });
+ formatMethod = typeof(string).GetMethod(nameof(string.Format), [typeof(IFormatProvider), typeof(string), typeof(object[])]);
Debug.Assert(formatMethod is not null);
return Call(formatMethod, FormatProvider, Constant(Format), FormatProvider, NewArrayInit(typeof(object), arguments));
}
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/ItemIndexExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/ItemIndexExpression.cs
index 0aafdb835..af52a8a53 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/ItemIndexExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/ItemIndexExpression.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
using Debug = System.Diagnostics.Debug;
@@ -64,6 +65,8 @@ public ItemIndexExpression(Expression value, bool fromEnd = false)
///
public override Type Type => typeof(Index);
+ [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(Index))]
+ [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Dependency of Index is declared explicitly")]
internal static Expression GetOffset(Expression index, Expression count)
=> index is ItemIndexExpression { IsFromEnd: false } itemIndex ? itemIndex.Value : Call(index, nameof(Index.GetOffset), null, count);
@@ -74,7 +77,7 @@ internal static Expression GetOffset(Expression index, Expression count)
/// Translated expression.
public override Expression Reduce()
{
- ConstructorInfo? ctor = typeof(Index).GetConstructor(new[] { typeof(int), typeof(bool) });
+ ConstructorInfo? ctor = typeof(Index).GetConstructor([typeof(int), typeof(bool)]);
Debug.Assert(ctor is not null);
return New(ctor, conversionRequired ? Convert(Value, typeof(int)) : Value, Constant(IsFromEnd));
}
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/LockExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/LockExpression.cs
index 36252f1fb..e360d689e 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/LockExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/LockExpression.cs
@@ -94,9 +94,9 @@ public Expression Body
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(Monitor))]
public override Expression Reduce()
{
- var monitorEnter = typeof(Monitor).GetMethod(nameof(Monitor.Enter), new[] { typeof(object) });
+ var monitorEnter = typeof(Monitor).GetMethod(nameof(Monitor.Enter), [typeof(object)]);
Debug.Assert(monitorEnter is not null);
- var monitorExit = typeof(Monitor).GetMethod(nameof(Monitor.Exit), new[] { typeof(object) });
+ var monitorExit = typeof(Monitor).GetMethod(nameof(Monitor.Exit), [typeof(object)]);
Debug.Assert(monitorExit is not null);
var body = TryFinally(Body, Call(monitorExit, SyncRoot));
return assignment is null ?
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/MemberBindings.cs b/src/DotNext.Metaprogramming/Linq/Expressions/MemberBindings.cs
index 9b22273ef..f8b0bb445 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/MemberBindings.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/MemberBindings.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
@@ -21,7 +22,7 @@ public MemberBindings()
///
/// The target type with the declared members.
/// A list of bindings.
- public IReadOnlyList Bind(Type target)
+ public IReadOnlyList Bind([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type target)
{
const MemberTypes memberTypes = MemberTypes.Field | MemberTypes.Property;
const BindingFlags memberFlags = BindingFlags.Public | BindingFlags.Instance;
diff --git a/src/DotNext.Metaprogramming/Linq/Expressions/MetaExpression.cs b/src/DotNext.Metaprogramming/Linq/Expressions/MetaExpression.cs
index 8122eb1a7..cc8a5633b 100644
--- a/src/DotNext.Metaprogramming/Linq/Expressions/MetaExpression.cs
+++ b/src/DotNext.Metaprogramming/Linq/Expressions/MetaExpression.cs
@@ -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;
@@ -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