Exemple #1
0
        private static void CollectionItems(
            object source,
            object target,
            MemberSettings settings,
            ReferencePairCollection referencePairs)
        {
            if (!Is.Enumerable(source, target))
            {
                return;
            }

            if (settings.ReferenceHandling == ReferenceHandling.Throw &&
                !settings.IsImmutable(source.GetType().GetItemType()))
            {
                throw State.Throw.ShouldNeverGetHereException("Should have been checked for throw before copy");
            }

            if (ArrayCopyer.TryGetOrCreate(source, target, out var copyer) ||
                ListOfTCopyer.TryGetOrCreate(source, target, out copyer) ||
                ListCopyer.TryGetOrCreate(source, target, out copyer) ||
                DictionaryTKeyTValueCopyer.TryGetOrCreate(source, target, out copyer) ||
                DictionaryCopyer.TryGetOrCreate(source, target, out copyer) ||
                SetOfTCopyer.TryGetOrCreate(source, target, out copyer))
            {
                copyer.Copy(source, target, settings, referencePairs);
                return;
            }

            if (source is IEnumerable || target is IEnumerable)
            {
                throw State.Throw.ShouldNeverGetHereException("Should be checked before");
            }
        }
 private static ErrorBuilder.TypeErrorsBuilder VerifyCore(MemberSettings settings, Type type)
 {
     return(ErrorBuilder.Start()
            .CheckRequiresReferenceHandling(type, settings, t => !settings.IsImmutable(t))
            .CheckIsCopyableEnumerable(type, settings)
            .CheckIndexers(type, settings));
 }
Exemple #3
0
            private static TypeErrors CreateErrors(Type type, MemberSettings settings, MemberPath path)
            {
                if (settings.IsImmutable(type))
                {
                    return(null);
                }

                var errors = ErrorBuilder.Start()
                             .CheckRequiresReferenceHandling(type, settings, x => !settings.IsImmutable(x))
                             .CheckIndexers(type, settings)
                             .CheckNotifies(type, settings)
                             .VerifyRecursive(type, settings, path, GetNodeErrors)
                             .Finnish();

                return(errors);
            }
Exemple #4
0
        internal static TypeErrorsBuilder CheckNotifies(this TypeErrorsBuilder typeErrors, Type type, MemberSettings settings)
        {
            if (settings.IsImmutable(type))
            {
                return(typeErrors);
            }

            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
                if (!typeof(INotifyCollectionChanged).IsAssignableFrom(type))
                {
                    return(typeErrors.CreateIfNull(type)
                           .Add(CollectionMustNotifyError.GetOrCreate(type)));
                }
            }
            else if (!typeof(INotifyPropertyChanged).IsAssignableFrom(type))
            {
                if (settings.IsIgnoringDeclaringType(type))
                {
                    return(typeErrors);
                }

                return(typeErrors.CreateIfNull(type)
                       .Add(TypeMustNotifyError.GetOrCreate(type)));
            }

            return(typeErrors);
        }
        internal static object CreateInstance(object sourceValue, MemberSettings settings)
        {
            if (sourceValue == null)
            {
                return(null);
            }

            var type = sourceValue.GetType();

            if (type.IsArray)
            {
                var constructor = type.GetConstructor(new[] { typeof(int) });
                var parameters  = new[] { type.GetProperty("Length").GetValue(sourceValue) };
                //// ReSharper disable once PossibleNullReferenceException nope, never null here
                var array = constructor.Invoke(parameters);
                return(array);
            }

            if (settings.IsImmutable(type))
            {
                return(sourceValue);
            }

            try
            {
                return(Activator.CreateInstance(type, true));
            }
            catch (Exception e)
            {
                throw Throw.CreateCannotCreateInstanceException(sourceValue, settings, e);
            }
        }
        private static void CollectionItems(
            object source,
            object target,
            MemberSettings settings,
            ReferencePairCollection referencePairs)
        {
            if (!Is.Enumerable(source, target))
            {
                return;
            }

            if (settings.ReferenceHandling == ReferenceHandling.Throw &&
                !settings.IsImmutable(source.GetType().GetItemType()))
            {
                throw State.Throw.ShouldNeverGetHereException("Should have been checked for throw before copy");
            }

            ICopyer copyer;
            if (ArrayCopyer.TryGetOrCreate(source, target, out copyer) ||
                ListOfTCopyer.TryGetOrCreate(source, target, out copyer) ||
                ListCopyer.TryGetOrCreate(source, target, out copyer) ||
                DictionaryTKeyTValueCopyer.TryGetOrCreate(source, target, out copyer) ||
                DictionaryCopyer.TryGetOrCreate(source, target, out copyer) ||
                SetOfTCopyer.TryGetOrCreate(source, target, out copyer))
            {
                copyer.Copy(source, target, settings, referencePairs);
                return;
            }

            if (source is IEnumerable || target is IEnumerable)
            {
                throw State.Throw.ShouldNeverGetHereException("Should be checked before");
            }
        }
        private static void Copy <T>(
            ISet <T> source,
            ISet <T> target,
            MemberSettings settings,
            ReferencePairCollection referencePairs)
        {
            if (Is.IsFixedSize(source, target) && source.Count != target.Count)
            {
                throw State.Copy.Throw.CannotCopyFixesSizeCollections(source, target, settings);
            }

            if (settings.IsImmutable(typeof(T)))
            {
                using (var borrow = HashSetPool <T> .Borrow(EqualityComparer <T> .Default))
                {
                    borrow.Value.UnionWith(source);
                    target.IntersectWith(borrow.Value);
                    target.UnionWith(borrow.Value);
                    return;
                }
            }

            switch (settings.ReferenceHandling)
            {
            case ReferenceHandling.Throw:
                break;

            case ReferenceHandling.References:
                using (var borrow = HashSetPool <T> .Borrow((x, y) => ReferenceEquals(x, y), x => RuntimeHelpers.GetHashCode(x)))
                {
                    borrow.Value.UnionWith(source);
                    target.IntersectWith(borrow.Value);
                    target.UnionWith(borrow.Value);
                }

                break;

            case ReferenceHandling.Structural:
                IEqualityComparer <T> comparer;
                if (!Set.TryGetComparer(source, out comparer))
                {
                    comparer = EqualityComparer <T> .Default;
                }

                var copyIngComparer = new CopyingComparer <T>(comparer, settings, referencePairs);
                using (var borrow = HashSetPool <T> .Borrow(copyIngComparer))
                {
                    borrow.Value.UnionWith(source);
                    target.IntersectWith(borrow.Value);
                    copyIngComparer.StartCopying();
                    target.UnionWith(borrow.Value);
                }

                return;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        internal static bool IsCopyValue(Type type, MemberSettings settings)
        {
            if (settings.IsImmutable(type) || settings.ReferenceHandling == ReferenceHandling.References)
            {
                return(true);
            }

            return(false);
        }
Exemple #9
0
        private static void Member <T>(
            T source,
            T target,
            MemberSettings settings,
            ReferencePairCollection referencePairs,
            IGetterAndSetter getterAndSetter)
        {
            var sv = getterAndSetter.GetValue(source);
            var tv = getterAndSetter.GetValue(target);

            if (getterAndSetter.IsInitOnly)
            {
                if (settings.IsImmutable(getterAndSetter.ValueType) || sv == null)
                {
                    return;
                }

                Sync(sv, tv, settings, referencePairs);
                return;
            }

            if (settings.IsImmutable(getterAndSetter.ValueType) || sv == null)
            {
                getterAndSetter.CopyValue(source, target);
                return;
            }

            bool created;
            bool needsSync;
            var  clone = CloneWithoutSync(sv, tv, settings, out created, out needsSync);

            if (created)
            {
                getterAndSetter.SetValue(target, clone);
            }

            if (needsSync)
            {
                Sync(sv, clone, settings, referencePairs);
            }
        }
Exemple #10
0
            internal static void CanCopyRoot(Type type, MemberSettings settings)
            {
                if (settings.IsImmutable(type))
                {
                    throw new NotSupportedException("Cannot copy the members of an immutable object");
                }

                if (typeof(IEnumerable).IsAssignableFrom(type) && !IsCopyableCollectionType(type))
                {
                    throw new NotSupportedException($"Can only copy the members of collections implementing {typeof(IList).Name} or {typeof(IDictionary).Name}");
                }
            }
Exemple #11
0
            private static TypeErrors CreateErrors(Type type, MemberSettings settings, MemberPath path)
            {
                if (settings.IsImmutable(type) || settings.TryGetCopyer(type, out var temp))
                {
                    return(null);
                }

                var errors = VerifyCore(settings, type)
                             .VerifyRecursive(type, settings, path, GetNodeErrors)
                             .Finnish();

                return(errors);
            }
Exemple #12
0
        private static bool TryCopyValue <T>(T x, T y, MemberSettings settings, out T result)
        {
            if (ReferenceEquals(x, y))
            {
                result = x;
                return(true);
            }

            if (x == null)
            {
                // ReSharper disable once ExpressionIsAlwaysNull R# not getting static analysis right here
                result = x;
                return(true);
            }

            if (settings.IsImmutable(x.GetType()))
            {
                result = x;
                return(true);
            }

            result = default(T);
            return(false);
        }
Exemple #13
0
        internal static TypeErrorsBuilder CheckNotifies(this TypeErrorsBuilder typeErrors, Type type, MemberSettings settings)
        {
            if (settings.IsImmutable(type))
            {
                return typeErrors;
            }

            if (type.IsValueType)
            {
                if (typeof(INotifyCollectionChanged).IsAssignableFrom(type) ||
                    typeof(INotifyPropertyChanged).IsAssignableFrom(type))
                {
                    return typeErrors.CreateIfNull(type)
                                     .Add(StructMustNotNotifyError.GetOrCreate(type));
                }

                return typeErrors;
            }

            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
                if (!typeof(INotifyCollectionChanged).IsAssignableFrom(type))
                {
                    return typeErrors.CreateIfNull(type)
                                           .Add(CollectionMustNotifyError.GetOrCreate(type));
                }
            }
            else if (!typeof(INotifyPropertyChanged).IsAssignableFrom(type))
            {
                if (settings.IsIgnoringDeclaringType(type))
                {
                    return typeErrors;
                }

                return typeErrors.CreateIfNull(type)
                                 .Add(TypeMustNotifyError.GetOrCreate(type));
            }

            return typeErrors;
        }