• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loresoft / EntityChange / 13417967502

19 Feb 2025 04:51PM UTC coverage: 45.43% (+5.7%) from 39.697%
13417967502

push

github

pwelter34
fix failing test

287 of 726 branches covered (39.53%)

Branch coverage included in aggregate %.

563 of 1145 relevant lines covered (49.17%)

73.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

13.71
/src/EntityChange/Reflection/ExpressionFactory.cs
1
#nullable disable
2

3
using System.Linq.Expressions;
4
using System.Reflection;
5

6
namespace EntityChange.Reflection;
7

8
internal static class ExpressionFactory
9
{
10
    public static Func<object, object[], object> CreateMethod(MethodInfo methodInfo)
11
    {
12
        if (methodInfo == null)
×
13
            throw new ArgumentNullException(nameof(methodInfo));
×
14

15
        // parameters to execute
16
        var instanceParameter = Expression.Parameter(typeof(object), "instance");
×
17
        var parametersParameter = Expression.Parameter(typeof(object[]), "parameters");
×
18

19
        // build parameter list
20
        var parameterExpressions = new List<Expression>();
×
21
        var paramInfos = methodInfo.GetParameters();
×
22
        for (int i = 0; i < paramInfos.Length; i++)
×
23
        {
24
            // (Ti)parameters[i]
25
            var valueObj = Expression.ArrayIndex(parametersParameter, Expression.Constant(i));
×
26

27
            Type parameterType = paramInfos[i].ParameterType;
×
28
            if (parameterType.IsByRef)
×
29
                parameterType = parameterType.GetElementType();
×
30

31
            var valueCast = Expression.Convert(valueObj, parameterType);
×
32

33
            parameterExpressions.Add(valueCast);
×
34
        }
35

36
        // non-instance for static method, or ((TInstance)instance)
37
        var instanceCast = methodInfo.IsStatic ? null : Expression.Convert(instanceParameter, methodInfo.DeclaringType);
×
38

39
        // static invoke or ((TInstance)instance).Method
40
        var methodCall = Expression.Call(instanceCast, methodInfo, parameterExpressions);
×
41

42
        // ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)
43
        if (methodCall.Type == typeof(void))
×
44
        {
45
            var lambda = Expression.Lambda<Action<object, object[]>>(methodCall, instanceParameter, parametersParameter);
×
46
            var execute = lambda.Compile();
×
47

48
            return (instance, parameters) =>
×
49
            {
×
50
                execute(instance, parameters);
×
51
                return null;
×
52
            };
×
53
        }
54
        else
55
        {
56
            var castMethodCall = Expression.Convert(methodCall, typeof(object));
×
57
            var lambda = Expression.Lambda<Func<object, object[], object>>(castMethodCall, instanceParameter, parametersParameter);
×
58

59
            return lambda.Compile();
×
60
        }
61
    }
62

63
    public static Func<object> CreateConstructor(Type type)
64
    {
65
        if (type == null)
×
66
            throw new ArgumentNullException(nameof(type));
×
67

68
        var typeInfo = type.GetTypeInfo();
×
69

70

71
        var constructorInfo = typeInfo.GetConstructor(Type.EmptyTypes);
×
72
        if (constructorInfo == null)
×
73
            throw new ArgumentException("Could not find constructor for type.", nameof(type));
×
74

75
        var instanceCreate = Expression.New(constructorInfo);
×
76

77
        var instanceCreateCast = typeInfo.IsValueType
×
78
            ? Expression.Convert(instanceCreate, typeof(object))
×
79
            : Expression.TypeAs(instanceCreate, typeof(object));
×
80

81
        var lambda = Expression.Lambda<Func<object>>(instanceCreateCast);
×
82

83
        return lambda.Compile();
×
84
    }
85

86
    public static Func<object, object> CreateGet(PropertyInfo propertyInfo)
87
    {
88
        if (propertyInfo == null)
39!
89
            throw new ArgumentNullException(nameof(propertyInfo));
×
90

91
        if (!propertyInfo.CanRead)
39!
92
            return null;
×
93

94
        var instance = Expression.Parameter(typeof(object), "instance");
39✔
95
        var declaringType = propertyInfo.DeclaringType;
39✔
96
        var getMethod = propertyInfo.GetGetMethod(true);
39✔
97

98
        var instanceCast = CreateCast(instance, declaringType, getMethod.IsStatic);
39✔
99

100
        var call = Expression.Call(instanceCast, getMethod);
39✔
101
        var valueCast = Expression.TypeAs(call, typeof(object));
39✔
102

103
        var lambda = Expression.Lambda<Func<object, object>>(valueCast, instance);
39✔
104
        return lambda.Compile();
39✔
105
    }
106

107
    public static Func<object, object> CreateGet(FieldInfo fieldInfo)
108
    {
109
        if (fieldInfo == null)
×
110
            throw new ArgumentNullException(nameof(fieldInfo));
×
111

112
        var instance = Expression.Parameter(typeof(object), "instance");
×
113
        var declaringType = fieldInfo.DeclaringType;
×
114

115
        var instanceCast = CreateCast(instance, declaringType, fieldInfo.IsStatic);
×
116

117
        var fieldAccess = Expression.Field(instanceCast, fieldInfo);
×
118
        var valueCast = Expression.TypeAs(fieldAccess, typeof(object));
×
119

120
        var lambda = Expression.Lambda<Func<object, object>>(valueCast, instance);
×
121
        return lambda.Compile();
×
122
    }
123

124
    public static Action<object, object> CreateSet(PropertyInfo propertyInfo)
125
    {
126
        if (propertyInfo == null)
×
127
            throw new ArgumentNullException(nameof(propertyInfo));
×
128

129
        if (!propertyInfo.CanWrite)
×
130
            return null;
×
131

132
        var instance = Expression.Parameter(typeof(object), "instance");
×
133
        var value = Expression.Parameter(typeof(object), "value");
×
134

135
        var declaringType = propertyInfo.DeclaringType;
×
136
        var propertyType = propertyInfo.PropertyType;
×
137
        var setMethod = propertyInfo.GetSetMethod(true);
×
138

139
        var instanceCast = CreateCast(instance, declaringType, setMethod.IsStatic);
×
140
        var valueCast = CreateCast(value, propertyType, false);
×
141

142
        var call = Expression.Call(instanceCast, setMethod, valueCast);
×
143
        var parameters = new[] { instance, value };
×
144

145
        var lambda = Expression.Lambda<Action<object, object>>(call, parameters);
×
146
        return lambda.Compile();
×
147
    }
148

149
    public static Action<object, object> CreateSet(FieldInfo fieldInfo)
150
    {
151
        if (fieldInfo == null)
×
152
            throw new ArgumentNullException(nameof(fieldInfo));
×
153

154
        var instance = Expression.Parameter(typeof(object), "instance");
×
155
        var value = Expression.Parameter(typeof(object), "value");
×
156

157
        var declaringType = fieldInfo.DeclaringType;
×
158
        var fieldType = fieldInfo.FieldType;
×
159

160
        var instanceCast = CreateCast(instance, declaringType, fieldInfo.IsStatic);
×
161
        var valueCast = CreateCast(value, fieldType, false);
×
162

163
        var member = Expression.Field(instanceCast, fieldInfo);
×
164
        var assign = Expression.Assign(member, valueCast);
×
165

166
        var parameters = new[] { instance, value };
×
167

168
        var lambda = Expression.Lambda<Action<object, object>>(assign, parameters);
×
169
        return lambda.Compile();
×
170
    }
171

172

173
    private static UnaryExpression CreateCast(ParameterExpression instance, Type declaringType, bool isStatic)
174
    {
175
        if (isStatic)
39!
176
            return null;
×
177

178
        // value as T is slightly faster than (T)value, so if it's not a value type, use that
179
        if (declaringType.GetTypeInfo().IsValueType)
39!
180
            return Expression.Convert(instance, declaringType);
×
181
        else
182
            return Expression.TypeAs(instance, declaringType);
39✔
183
    }
184
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc