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

loresoft / EntityChange / 10792597827

10 Sep 2024 12:38PM CUT coverage: 39.608%. Remained the same
10792597827

push

github

web-flow
Merge pull request #103 from loresoft/dependabot/nuget/MinVer-6.0.0

Bump MinVer from 5.0.0 to 6.0.0

237 of 731 branches covered (32.42%)

Branch coverage included in aggregate %.

571 of 1309 relevant lines covered (43.62%)

60.49 hits per line

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

13.71
/src/EntityChange/Reflection/ExpressionFactory.cs
1
using System.Linq.Expressions;
2
using System.Reflection;
3

4
namespace EntityChange.Reflection;
5

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

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

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

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

29
            var valueCast = Expression.Convert(valueObj, parameterType);
×
30

31
            parameterExpressions.Add(valueCast);
×
32
        }
33

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

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

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

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

57
            return lambda.Compile();
×
58
        }
59
    }
60

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

66
        var typeInfo = type.GetTypeInfo();
×
67

68

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

73
        var instanceCreate = Expression.New(constructorInfo);
×
74

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

79
        var lambda = Expression.Lambda<Func<object>>(instanceCreateCast);
×
80

81
        return lambda.Compile();
×
82
    }
83

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

89
        if (!propertyInfo.CanRead)
42!
90
            return null;
×
91

92
        var instance = Expression.Parameter(typeof(object), "instance");
42✔
93
        var declaringType = propertyInfo.DeclaringType;
42✔
94
        var getMethod = propertyInfo.GetGetMethod(true);
42✔
95

96
        var instanceCast = CreateCast(instance, declaringType, getMethod.IsStatic);
42✔
97

98
        var call = Expression.Call(instanceCast, getMethod);
42✔
99
        var valueCast = Expression.TypeAs(call, typeof(object));
42✔
100

101
        var lambda = Expression.Lambda<Func<object, object>>(valueCast, instance);
42✔
102
        return lambda.Compile();
42✔
103
    }
104

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

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

113
        var instanceCast = CreateCast(instance, declaringType, fieldInfo.IsStatic);
×
114

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

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

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

127
        if (!propertyInfo.CanWrite)
×
128
            return null;
×
129

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

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

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

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

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

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

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

155
        var declaringType = fieldInfo.DeclaringType;
×
156
        var fieldType = fieldInfo.FieldType;
×
157

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

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

164
        var parameters = new[] { instance, value };
×
165

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

170

171
    private static UnaryExpression CreateCast(ParameterExpression instance, Type declaringType, bool isStatic)
172
    {
173
        if (isStatic)
42!
174
            return null;
×
175

176
        // value as T is slightly faster than (T)value, so if it's not a value type, use that
177
        if (declaringType.GetTypeInfo().IsValueType)
42!
178
            return Expression.Convert(instance, declaringType);
×
179
        else
180
            return Expression.TypeAs(instance, declaringType);
42✔
181
    }
182
}
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

© 2025 Coveralls, Inc