Beispiel #1
0
        public void TypeSpace_ArgumentChecks()
        {
            var ts = new TypeSpace();

            AssertEx.ThrowsException <ArgumentNullException>(() => ts.GetMember(member: null), ex => Assert.AreEqual(ex.ParamName, "member"));
            AssertEx.ThrowsException <ArgumentNullException>(() => ts.GetConstructor(constructor: null), ex => Assert.AreEqual(ex.ParamName, "constructor"));
            AssertEx.ThrowsException <ArgumentNullException>(() => ts.GetField(field: null), ex => Assert.AreEqual(ex.ParamName, "field"));
            AssertEx.ThrowsException <ArgumentNullException>(() => ts.GetMethod(method: null), ex => Assert.AreEqual(ex.ParamName, "method"));
            AssertEx.ThrowsException <ArgumentNullException>(() => ts.GetProperty(property: null), ex => Assert.AreEqual(ex.ParamName, "property"));
            AssertEx.ThrowsException <ArgumentNullException>(() => ts.ConvertType(type: null), ex => Assert.AreEqual(ex.ParamName, "type"));
            AssertEx.ThrowsException <ArgumentNullException>(() => ts.MapType(type: null, typeSlim: null), ex => Assert.AreEqual(ex.ParamName, "type"));
            AssertEx.ThrowsException <ArgumentNullException>(() => ts.MapType(typeof(int), typeSlim: null), ex => Assert.AreEqual(ex.ParamName, "typeSlim"));
        }
Beispiel #2
0
            /// <summary>
            /// Visits a member assignment slim tree node to produce a member assignment,
            /// taking implicit conversions for primitive data model types into account.
            /// </summary>
            /// <param name="node">Slim expression representation of the assignment.</param>
            /// <param name="expression">Expression assigned to the member, obtained from recursive conversion steps.</param>
            /// <returns>Member assignment node.</returns>
            protected override MemberAssignment MakeMemberAssignment(MemberAssignmentSlim node, Expression expression)
            {
                var member = TypeSpace.GetMember(node.Member);

                var lhsType = GetMemberAssignmentMemberType(member);
                var rhsType = expression.Type;

                // This case occurs when an enum is used in a known type and the underlying type of the enum
                // is used during anonymization. For example:
                //
                //    xs.Select(x => new Person { Sex = Sex.Male, Age = x })
                //
                // Erasure of the enum results in the following anonymized expression:
                //
                //    xs.Select(x => new <>__Record { entity://person/sex = 1, entity://person/age = x })
                //
                // Upon unification and reconstruction of the expression, the record type is unified against
                // the Person type, and an assignment incompatibility occurs for Sex = 1.
                //
                // A similar case exists during recursive rewriting of a subexpression whose type, declared
                // on a known type, is an enum. For example:
                //
                //    xs.Select(x => new Person { Sex = x.Sex, Age = 21 })
                //
                // Erasure of the enum results in the following anonymized expression:
                //
                //    xs.Select(x => new <>__Record { entity://person/sex = x.entity://ape/sex, entity://person/age = 21 })
                //
                // This time around, as the type of "x" gets resolved, the x.entity://ape/sex subexpression is
                // turned into x.Sex on the known type, which is an enum. Assignment to the record type's int
                // property now fails because of lack of conversion.
                if (lhsType != rhsType && (IsEnumAssignableToUnderlyingType(lhsType, rhsType) || IsEnumAssignableToUnderlyingType(rhsType, lhsType)))
                {
                    expression = Expression.Convert(expression, lhsType);
                }

                return(base.MakeMemberAssignment(node, expression));
            }
Beispiel #3
0
 protected static MemberInfo MemberInfoRoundtrip(MemberInfo m, TypeSpace ts, InvertedTypeSpace its)
 {
     return(its.GetMember(ts.GetMember(m)));
 }