예제 #1
0
        private ManualTypeDescriberBuilder WithDeserializeMember(TypeInfo?forType, Setter?setter, string?name, Parser?parser, MemberRequired required, Reset?reset)
        {
            if (forType == null)
            {
                Throw.ArgumentNullException(nameof(forType));
            }

            if (setter == null)
            {
                Throw.ArgumentNullException(nameof(setter));
            }

            if (name == null)
            {
                Throw.ArgumentNullException(nameof(name));
            }

            if (parser == null)
            {
                Throw.ArgumentNullException(nameof(parser));
            }

            var toAdd = DeserializableMember.Create(forType, name, setter, parser, required, reset);

            if (!Deserializers.TryGetValue(forType, out var d))
            {
                Deserializers[forType] = d = ImmutableArray.CreateBuilder <DeserializableMember>();
            }

            d.Add(toAdd);

            return(this);
        }
예제 #2
0
        /// <summary>
        /// Enumerate all columns to deserialize.
        /// </summary>
        public virtual IEnumerable <DeserializableMember> EnumerateMembersToDeserialize(TypeInfo forType)
        {
            var buffer = new List <(DeserializableMember Member, int?Position)>();

            foreach (var p in forType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance))
            {
                if (!ShouldDeserialize(forType, p))
                {
                    continue;
                }

                var name       = GetDeserializationName(forType, p);
                var setter     = GetSetter(forType, p);
                var parser     = GetParser(forType, p);
                var order      = GetPosition(forType, p);
                var isRequired = GetIsRequired(forType, p);
                var reset      = GetReset(forType, p);

                buffer.Add((DeserializableMember.Create(forType, name, setter, parser, isRequired, reset), order));
            }

            foreach (var f in forType.GetFields())
            {
                if (!ShouldDeserialize(forType, f))
                {
                    continue;
                }

                var name       = GetDeserializationName(forType, f);
                var parser     = GetParser(forType, f);
                var order      = GetPosition(forType, f);
                var isRequired = GetIsRequired(forType, f);
                var reset      = GetReset(forType, f);

                buffer.Add((DeserializableMember.Create(forType, name, f, parser, isRequired, reset), order));
            }

            buffer.Sort(TypeDescribers.DeserializableComparer);

            foreach (var(member, _) in buffer)
            {
                yield return(member);
            }
        }
예제 #3
0
        private static DeserializableMember Map(TypeInfo ontoType, DeserializableMember member)
        {
            MethodInfo resetOnType = null;

            if (member.Reset != null)
            {
                var surrogateReset        = member.Reset;
                var surrogateResetBinding =
                    // explicitly ignoring DeclaredOnly; shadowing is fine
                    (surrogateReset.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic) |
                    (surrogateReset.IsStatic ? BindingFlags.Static : BindingFlags.Instance);

                resetOnType = ontoType.GetMethod(surrogateReset.Name, surrogateResetBinding);
                if (resetOnType == null)
                {
                    Throw.InvalidOperationException($"No equivalent to {resetOnType} found on {ontoType}");
                }
            }

            if (member.Field != null)
            {
                var surrogateField        = member.Field;
                var surrogateFieldBinding =
                    // explicitly ignoring DeclaredOnly; shadowing is fine
                    (surrogateField.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic) |
                    (surrogateField.IsStatic ? BindingFlags.Static : BindingFlags.Instance);

                var fieldOnType = ontoType.GetField(surrogateField.Name, surrogateFieldBinding);
                if (fieldOnType == null)
                {
                    Throw.InvalidOperationException($"No equivalent to {surrogateField} found on {ontoType}");
                }

                if (fieldOnType.FieldType != surrogateField.FieldType)
                {
                    Throw.InvalidOperationException($"Field {fieldOnType} type ({fieldOnType.FieldType}) does not match surrogate field {surrogateField} type ({surrogateField.FieldType})");
                }
                return(DeserializableMember.Create(ontoType, member.Name, fieldOnType, member.Parser, member.IsRequired, resetOnType));
            }

            var surrogateSetter        = member.Setter;
            var surrogateSetterBinding =
                // explicitly ignoring DeclaredOnly; shadowing is fine
                (surrogateSetter.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic) |
                (surrogateSetter.IsStatic ? BindingFlags.Static : BindingFlags.Instance);

            var setterOnType = ontoType.GetMethod(surrogateSetter.Name, surrogateSetterBinding);

            if (setterOnType == null)
            {
                Throw.InvalidOperationException($"No equivalent to {surrogateSetter} found on {ontoType}");
            }

            var paramsOnType      = setterOnType.GetParameters();
            var paramsOnSurrogate = surrogateSetter.GetParameters();

            if (paramsOnType.Length != paramsOnSurrogate.Length)
            {
                Throw.InvalidOperationException($"Parameters for {setterOnType} do not match parameters for {surrogateSetter}");
            }

            for (var i = 0; i < paramsOnType.Length; i++)
            {
                var pOnType      = paramsOnType[i];
                var pOnSurrogate = paramsOnSurrogate[i];

                if (pOnType.ParameterType != pOnSurrogate.ParameterType)
                {
                    Throw.InvalidOperationException($"Parameter #{(i + 1)} on {setterOnType} does not match same parameter on {surrogateSetter}");
                }
            }

            return(DeserializableMember.Create(ontoType, member.Name, setterOnType, member.Parser, member.IsRequired, resetOnType));
        }